假设我有以下模型:
class Author(ndb.Model)
books = ndb.KeyProperty(kind='Book', repeated=True)
class Book(ndb.Model)
title = ndb.StringProperty()
因此,在某个时刻,你会有一位作者列出n
的书籍列表。
问题:当我编辑一本书时,如何在不参考"当前"作者的情况下更改作者?是否需要在Book
上添加与KeyProperty
的反向关系?
当更换作者时,我必须从旧作者的列表中删除这本书,并将其添加到新作者中。这感觉有点麻烦。有更好的方法吗?
奖励问题:如果一本书被删除了怎么办?作者的图书列表中将有一个None
值。我必须把它取下来吗?
注意:我使用了重复的KeyProperty,因为这使书籍的订购变得容易,这在我的情况下很重要。
当我编辑一本书时,如何在不参考"当前"作者的情况下更改作者?
可以使用ndb.Model.allocate_ids
在实体保存之前保留密钥
我需要在Book上添加一个具有KeyProperty的反向关系吗?
考虑到您的型号,添加反向查找密钥可以让您的生活更轻松
如果一本书被删除了怎么办?在作者的图书列表中会有一个None值。我必须把它取下来吗?
在这种情况下,Auther.books
中的密钥不会自动变为空。你必须自己把它取下来。
我使用了一个重复的KeyProperty,因为这样可以很容易地订购书籍,这对我来说很重要。
一个潜在的问题是,一个实体的大小限制为1mb。如果一位作家是一位多产的作家(例如Edwy Searles Brooks出版了800+部作品),那么他可能会超过这个限制。
我会这样设计模型:
class Author(ndb.Model):
name = ndb.StringProperty()
class Book(ndb.Model):
authors = ndb.KeyProperty('Author', required=True) # Usually it is at most a couple of authors
title = ndb.StringProperty()
要查找id为1234的特定作者所写的所有书籍,您可以
Book.query(Book.authors == ndb.Key('Author', 1234)).fetch()
显然,书籍的订购必须明确存储,我建议使用第三个实体来跟踪这些信息:
class BookList(ndb.Model):
name = ndb.StringProperty()
book_keys = ndb.KeyProperty(kind='Book', repeated=True)
然后你可以用这种方式检索书籍
stephen_king_book_list = stephen_king_book_list_key.get()
books = ndb.get_multi(stephen_king_book_list.book_keys)
# Some of key can lead to None if the underlying book is already deleted
# You can define some background job to sweep clean the list from time to time
# But let filter out the bad guys first
books = [b for b in books if b]
如果你认为你的列表会非常长,你可以把一个列表分解成一些片段,比如链表结构
class BookList(ndb.Model):
prev_segment = ndb.KeyProperty(kind='BookList', required=False)
next_segment = ndb.KeyProperty(kind='BookList', required=False)
name = ndb.StringProperty()
book_keys = ndb.KeyProperty(kind='Book', repeated=True)
您可以通过以下方式轻松找到第一段:
starting_point = BookList.query(BookList.name == 'Stephen_King',
BookList.prev_segment == None
).fetch()
当然,如果插入非常频繁,您可能需要使用另一种结构来保存图书列表
你的关系真的错了。您应该在Book上有一个指向Author的KeyProperty;然后,如果您想查询单个作者的所有书籍,您可以在author键上进行查询。