在我的数据存储区中,我有一个实体Book
,该实体引用了Owner
,其中引用了ContactInfo
,其中包含属性zipcode
。我想查询某个邮政编码中的所有书籍。我怎样才能做到这一点?我知道我无法在我能做的地方写一个查询:
q = db.Query(Book).filter('owner.contact_info.zipcode =', 12345)
答案 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)
如果联系信息是一个单独的模型,您首先需要找到ContactInfo
个zipcode == 12345
个实体,然后查找引用Owner
的所有ContactInfo
个实体实体,然后查找引用这些Book
实体的所有Owner
实体。
如果您仍然可以更改模型定义,那么在ContactInfo
模型中至少Owner
进行非规范化可能是明智的,也可能在内部Owner
进行非规范化每个Book
。