Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.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
Python 实体组、引用属性或键作为字符串_Python_Google App Engine_Google Cloud Datastore - Fatal编程技术网

Python 实体组、引用属性或键作为字符串

Python 实体组、引用属性或键作为字符串,python,google-app-engine,google-cloud-datastore,Python,Google App Engine,Google Cloud Datastore,在gae平台上构建一些应用程序之后,我通常在每个应用程序的数据存储中使用不同模型之间的一些关系。我经常发现自己需要查看同一父项的记录(比如将所有条目与同一父项匹配) 从一开始,我就使用db.ReferenceProperty来处理关系,如: class Foo(db.Model): name = db.StringProperty() class Bar(db.Model): name = db.StringProperty() parentFoo = db.Refer

在gae平台上构建一些应用程序之后,我通常在每个应用程序的数据存储中使用不同模型之间的一些关系。我经常发现自己需要查看同一父项的记录(比如将所有条目与同一父项匹配)

从一开始,我就使用db.ReferenceProperty来处理关系,如:

class Foo(db.Model):
    name = db.StringProperty()

class Bar(db.Model):
    name = db.StringProperty()
    parentFoo = db.ReferanceProperty(Foo)

fooKey = someFooKeyFromSomePlace
bars = Bar.all()
for bar in bar:
    if bar.parentFoo.key() == fooKey:
        // do stuff
但最近我放弃了这种方法,因为
bar.parentFoo.key()
每次都会生成一个子查询来获取Foo。我现在使用的方法是将每个
Foo
键作为字符串存储在
Bar.parentFoo
上,这样我可以将其与
someFooKeyFromSomePlace
进行字符串比较,并消除所有子查询开销

现在我开始研究实体组,想知道这是否是更好的方法?我真的不知道如何使用它们

至于以上两种方法,我想知道使用它们有什么缺点吗?可以使用存储的密钥字符串返回并在***中咬我。最后但并非最不重要的是,有没有更快的方法来实现这一点?

提示:

替换

bar.parentFoo.key() == fooKey

Bar.parentFoo.get_value_for_datastore(bar) == fooKey
为了避免额外的查找,只需从
ReferenceProperty


> P>当您设计模块时,还需要考虑是否要在事务中保存此项。但是,仅当需要使用事务时才执行此操作

另一种方法是指定父对象,如下所示:

from google.appengine.ext import db

class Foo(db.Model):
    name = db.StringProperty()

class Bar(db.Model):
    name = db.StringProperty()

def _save_entities( foo_name, bar_name ):
    """Save the model data"""
    foo_item = Foo( name = foo_name )
    foo_item.put()    
    bar_item = Bar( parent = foo_item, name = bar_name )
    bar_item.put()

def main():
    # Run the save in a transaction, if any fail this should all roll back
    db.run_in_transaction( _save_transaction, "foo name", "bar name" )

    # to query the model data using the ancestor relationship
    for item in bar_item.gql("WHERE ANCESTOR IS :ancestor", ancestor = foo_item.key()).fetch(1000):
        # do stuff

我不确定您想用这个示例代码块做什么,但我感觉它可以通过以下方式完成:

bars = Bar.all().filter("parentFoo " = SomeFoo)
对于实体组,它们主要用于在事务中更改多个内容,因为appengine仅将其限制为同一组中的实体;此外,appengine允许使用祖先过滤器(),这可能很有用,具体取决于您需要做什么。有了上面的代码,如果将Bar的父级设置为Foo,您还可以非常轻松地使用祖先查询

如果您的目的仍然需要大量的“子查询”,那么Nick Johnson在这里介绍了一种简洁的预取模式:它基本上以一个巨大的get而不是一堆小get的形式获取实体集中所需的所有属性,从而消除了大量的开销。但是请注意他的警告,特别是关于在使用此预取方法时更改实体属性的警告


虽然不是很具体,但这就是我能给你的全部信息,直到你更确切地说出你在这里到底想做什么。

< P>我想你也应该考虑一下。这将帮助您获取单个父实体的所有子实体。 宝马=汽车(品牌=“宝马”) bmw.put()


更多建模参考。您可以引用此

是否有任何原因不使用
Bar.all().filter(“parentFoo=,fooKey)
,或者这仅仅是因为您简化了此问题?仅针对以下问题:)双重提示:如果您仅使用值进行键比较,请使用KeyProperty而不是ReferenceProperty。如何避免额外的查找?我的意思是
get\u value\u for\u datastore
听起来像是对数据库的查询。我可能弄错了。
get\u value\u for_datastore
只获取存储在
ReferenceProperty
本身中的
键,因此不需要数据存储RPC。同样,Calvin的方法通过完全取消
ReferenceProperty
取消引用的魔力来避免查找,因此,您可以从数据存储中显式地获取相关实体,而无需借助
bar.parentFoo
Nice,它会派上用场。但不幸的是,我将所有的
与同一个父项进行了比较,并将其放入了自己的列表中。因此,检查它是否将foo1作为父对象,并将其放入foo1List,依此类推。使用
run\u-in\u-transaction
而不是调用
\u-save\u-transaction()
?我已经更新了代码,使之更清晰一些,即_-save\u-entities()将尝试保存Foo和Bar,但如果Bar方法未能保存,则会保留孤立的Foo实体。当在事务中运行时,如果其中一个保存失败,那么两个保存都将回滚,并且不会向Bigtable提交任何内容。感谢链接,它提供了很多帮助。这个小问题我不知道如何更具体。我在寻找指针,从某种一般意义上说,如何存储模型之间的关系。然后用不同的方法进行撤退。
lf = Wheel(parent=bmw,position="left_front")
lf.put()

lb = Wheel(parent=bmw,position="left_back")
lb.put()

bmwWheels = Wheel.all().ancestor(bmw)