Google app engine 在某些情况下,“应用程序引擎”;通过“U键”获取“U名称”;使用现有键名调用将返回None

Google app engine 在某些情况下,“应用程序引擎”;通过“U键”获取“U名称”;使用现有键名调用将返回None,google-app-engine,google-cloud-datastore,data-modeling,Google App Engine,Google Cloud Datastore,Data Modeling,我遇到了一个奇怪的问题,在使用应用程序引擎ORM进行get\u by\u key\u name调用之前,我从未见过这个问题 在任何情况下,人们都会假设,以下情况不会返回零: Model.get_by_key_name(Model.all().get().key().name()) 然而,这就是我发现某些键名可以做到的。只有在少数情况下,我使用开放ID URL作为密钥名称属性,如下所示: https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3d

我遇到了一个奇怪的问题,在使用应用程序引擎ORM进行
get\u by\u key\u name
调用之前,我从未见过这个问题

在任何情况下,人们都会假设,以下情况不会返回零:

Model.get_by_key_name(Model.all().get().key().name())
然而,这就是我发现某些键名可以做到的。只有在少数情况下,我使用开放ID URL作为密钥名称属性,如下所示:

https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3
(为了保护无辜,我换了几个角色)

也许是“#”符号

解决方案:正如Nick Johnson所建议的,我需要修改查询,因为 实体有父项:

entity = Model.all().get()
Model.get_by_key_name(entity.key().name(), parent=entity.parent_key())

不管是什么情况,如果出现无法使用密钥名获取实体的情况,则首先不应允许将其用作密钥名

出于好奇,您是在生产环境中看到这一点,还是在sdk中看到这一点,或者两者都看到了

我尝试在中使用您的示例密钥名复制它,但无法:

>>> class Foo(db.Expando):
  pass
>>> Foo(key_name='https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3').put()
datastore_types.Key.from_path(u'Foo', u'https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3', _app_id_namespace=u'shell')
>>> Foo.get_by_key_name('https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3')
<__main__.Foo object at 0x75f9c1aa9181d78>
>类Foo(db.Expando):
通过
>>>Foo(key_name=)https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3)。put()
数据存储\类型.Key.from\路径(u'Foo',u'https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3',_app_id_namespace=u'shell')
>>>Foo.get\u by\u key\u name('https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3')
(当然,我没有使用您的模型类层次结构,您暗示这可能是触发它的原因。)

如果查询返回的实体是其他实体的子实体,则model.get\u by\u key\u name(model.all().get().key().name())将失败。不带父参数的get_by_key_name查找没有父项的实体,而查询可以返回子实体

例如:

a = Model1()
a.put()
b = Model2(parent=a)
b.put()
Model2.get_by_key_name(Model2.all().get().key().name()) # Fails to return anything
Model2.get(Model2.all().get().key()) # Works as expected

现在我再仔细考虑一下,我已经有了一些这样的实体一段时间了,没有任何问题。也许在最新的SDK版本中引入了这个bug。我知道已经有了一些更改,允许使用以整数开头的键名等,所以可能最近引入了此错误。我将此作为一个问题提交:还尝试刷新数据存储和数据存储历史记录,并确保它只影响单个模型。有一个单一的继承层,但它不会影响任何其他继承模型,因此这似乎不是问题的根源。+1“如果存在无法使用键名获取实体的情况,那么首先不应该允许将其用作键名。”这通常不会发生。非常奇怪的是,它只发生在一个模型上,正如我所说的,我是如何实现这个模型的,没有什么区别。它只继承了具有一些实用方法的db.Model子类,而这以前从未引起过问题。我将在生产环境中测试它,并很快再次更新。在生产环境中,它的行为方式完全相同,除了这个特定的模型之外,它使用所有的模型,并且只使用我最近创建的实体。该模型被称为“保证”,但我认为这真的不应该有什么不同。再一次明确地说,我发现无论我使用什么密钥名称,这种行为都会发生。这就解决了它。现在我再看一遍文档,它就在那里。谢谢你的帮助。希望这个答案能帮助其他遇到这个问题的人。