关于Google App Engine中ReferenceProperty的查询

2 投票
3 回答
2192 浏览
提问于 2025-04-16 14:33

我有两种实体,它们之间有相互关联,比如:

class Entity1(db.Expando):
     prop1=db.StringProperty()
     prop2=db.StringProperty()

class Entity2(db.Expando):
     prop3=db.ReferenceProperty(Entity1)
     prop4=db.StringProperty()

我可以写一个查询来获取这些信息吗:

q=Entity2.all().filter("prop3.prop1 =",somevalue)

这里的prop3是一个引用,它指向某种类型的Entity1的实体。我想知道所有那些类型为Entity2的实体,它们引用的Entity1实体的prop1属性值是某个特定值。

3 个回答

0

将实体2定义为:

class Entity2(db.Expando):
     entity_1_ref = db.ReferenceProperty(Entity1, collection_name = "set_of_entity_2_elements")
     prop4=db.StringProperty()

这段代码定义了一个集合名称,可以从引用的另一边进行操作(在这个例子中是Entity1)。我把prop3改成了一个更合适的名字。

现在你可以使用 q = entity_1_object.set_of_entity_2_elements 这个新属性来获取所有Entity1对象的相关元素,这样就能得到你想要的结果。

想了解更多信息,可以深入阅读这篇文章:http://code.google.com/appengine/articles/modeling.html

更新: 抱歉,我之前说错了。上面的建议并不能只获取那些 entity_1_object.prop1 == somevalue 的元素。

你仍然可以通过其他方式来获取,如下所示:

for obj in q:
    if ( obj.prop1 == somevalue):
        # Do your processing here

或者

for obj in q:
    if ( obj.prop1 != somevalue):
        # Delete this object from the list 'q'

但显然这不是最好的方法。我们等着更好的答案吧!

1

Google Datastore不支持连接查询。你可以获取所有Entity2的实体,然后进行一些处理来实现你想要的效果。这和@Mani建议的有点类似。不过你可以这样做:

entities2 = Entity2.all()
for entity2 in entities2:
   Entity1= entity.prop3.get()
    if Entity1.prop1== somevalue:
       #Do your processing here
2

在我的例子中,我首先获取了一个引用属性的键,用来作为查询的过滤条件。然后,你可以根据这个键进行过滤,数量和你找到的键的数量是一样的。

举个例子:

模型:

class Order(db.Model):
    waiter = db.ReferenceProperty(Waiter,required=True)
    date=db.DateTimeProperty(required=True)
    delivered=db.BooleanProperty(default=False)

class Waiter(db.Model):
    firstname=db.StringProperty(required=True)
    lastname=db.StringProperty(required=True)
    uuid=db.StringProperty(required=True)

网络请求的功能:

def get(self):
        waiteruuid=self.request.get("waiter")
        q=Waiter.all()
        q.filter('uuid =', waiteruuid)
        waiterkey=q.get()
        result={}
        result['orders']=[]
        q=Order.all()
        if waiteruuid:
            q.filter('waiter =', waiterkey)
        orders=q.run()

撰写回答