Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine 如果我使用祖先关系创建密钥,google app engine数据存储获取将失败_Google App Engine_Google Cloud Datastore_Google App Engine Python_Ancestor - Fatal编程技术网

Google app engine 如果我使用祖先关系创建密钥,google app engine数据存储获取将失败

Google app engine 如果我使用祖先关系创建密钥,google app engine数据存储获取将失败,google-app-engine,google-cloud-datastore,google-app-engine-python,ancestor,Google App Engine,Google Cloud Datastore,Google App Engine Python,Ancestor,当我将消息插入数据存储时,我使用消息的序列号创建一个键,并与发送消息的用户创建一个祖先关系。当我尝试使用仅从序列号创建的密钥检索消息时,它失败了。如果我将插入更改为使用仅基于序列号的键,则以后的检索将成功 代码方面 此操作失败: 存储: p_key = ndb.Key(StoredBcastMsg,sendingUser) c_key = ndb.Key(StoredBcastMsg,prof['seqNum'],parent=p_key) prof['key']=c_key StoredBca

当我将消息插入数据存储时,我使用消息的序列号创建一个键,并与发送消息的用户创建一个祖先关系。当我尝试使用仅从序列号创建的密钥检索消息时,它失败了。如果我将插入更改为使用仅基于序列号的键,则以后的检索将成功

代码方面

此操作失败:

存储:

p_key = ndb.Key(StoredBcastMsg,sendingUser)
c_key = ndb.Key(StoredBcastMsg,prof['seqNum'],parent=p_key)
prof['key']=c_key
StoredBcastMsg(**prof).put()
prof['key']=c_key
StoredBcastMsg(**prof).put()
c_key = ndb.Key(StoredBcastMsg,prof['seqNum'])
检索失败

msgToRet=ndb.Key(StoredBcastMsg,seqNum).get() #Fails even though sequence number is there in the store
成功:

存储:

p_key = ndb.Key(StoredBcastMsg,sendingUser)
c_key = ndb.Key(StoredBcastMsg,prof['seqNum'],parent=p_key)
prof['key']=c_key
StoredBcastMsg(**prof).put()
prof['key']=c_key
StoredBcastMsg(**prof).put()
c_key = ndb.Key(StoredBcastMsg,prof['seqNum'])
检索成功:

msgToRet=ndb.Key(StoredBcastMsg,seqNum).get() #Succeeds

这是预期的行为吗?我认为在创建密钥时添加parent=标记的唯一区别是创建一个祖先关系,该关系允许有效地回答诸如“给我用户X发送的所有消息”之类的查询。

父密钥是子密钥的一部分,您需要完整密钥来检索实体

因此,要检索子实体,您需要知道完整密钥,这意味着您需要知道父密钥

注意:通过键的父子关系不会创建普通SQL数据库所具有的关系关系。它只是将父级和子级放在同一个“实体组”(用于将实体放在同一服务器上的别致的词)中,这样您就可以在它们上进行事务处理。

正如您上面所说:

p_key = ndb.Key(StoredBcastMsg,sendingUser)
c_key = ndb.Key(StoredBcastMsg,prof['seqNum'],parent=p_key)
prof['key']=c_key
StoredBcastMsg(**prof).put()
这是成功的。要检索此实体,必须使用完全相同的密钥:

msgToRet=c_key.get()
或者,以较长的格式:

p_key = ndb.Key(StoredBcastMsg,sendingUser)
msgToRet=ndb.Key(StoredBcastMsg,seqNum,parent=p_key).get()

不,你对祖先的目的的评估是错误的。见下面的答案。它实际上是关于实体组的。如果所有查询都是父/子关系,并且不需要或不需要实体组,则可以使用普通查询。此外,不能更改实体组的祖先。如果您希望更改实体组中的父项,则必须使用不同的键删除和创建。谢谢您的回答。所以,如果我使用序列号作为键,看起来我需要按属性过滤的种类进行查询,以获得我想要的内容(获取用户X发送的所有消息)。