Google App Engine:数据存储区查询,其中WHERE子句指向引用属性

时间:2013-09-23 05:23:57

标签: google-app-engine

在我的数据存储区中,我有一个实体Book,该实体引用了Owner,其中引用了ContactInfo,其中包含属性zipcode。我想查询某个邮政编码中的所有书籍。我怎样才能做到这一点?我知道我无法在我能做的地方写一个查询:

q = db.Query(Book).filter('owner.contact_info.zipcode =', 12345)

2 个答案:

答案 0 :(得分:2)

这正是无法对App Engine数据存储区执行的操作。它不是关系数据库,您不能将其作为一个查询。这意味着它不支持JOIN,而且不能跨实体类型进行查询。

因此,在创建数据模型时遵循完整的规范化表单通常不是一个好主意。除非你有充分的理由将它们分开,否则ContactInfo几乎肯定会与所有者合并。您可能还想在所有者上定义一个重复的ReferenceProperty来记录books_owned:然后你可以做一个简单的查询,有些人可以得到所有的书:

owners = db.Query(Owner).filter('zipcode', 12345)
books = []
for owner in owners:
    book_ids.extend(owner.books_owned)
books = db.get(book_ids)

修改该字段如下所示:

class Owner(db.Model):
    ...
    books_owned = db.ListProperty(db.Key)

如果更新架构,则现有实体不会发生任何事情:您需要浏览它们(可能使用远程API)并更新它们以添加新数据。请注意,您可以直接设置属性,但不需要进行数据库迁移。

答案 1 :(得分:0)

如果联系信息是一个单独的模型,您首先需要找到ContactInfozipcode == 12345个实体,然后查找引用Owner的所有ContactInfo个实体实体,然后查找引用这些Book实体的所有Owner实体。

如果您仍然可以更改模型定义,那么在ContactInfo模型中至少Owner进行非规范化可能是明智的,也可能在内部Owner进行非规范化每个Book