我将实体 A 存储在 appengine 上的数据存储区中。A 的 id 类型为 Long。我想保留对 A 字段所做的所有更改的历史记录。在实体上执行此类版本的最佳实践是什么?我更喜欢与 A 的子类一起工作并且尽可能自动化的解决方案。
谢谢!
我将实体 A 存储在 appengine 上的数据存储区中。A 的 id 类型为 Long。我想保留对 A 字段所做的所有更改的历史记录。在实体上执行此类版本的最佳实践是什么?我更喜欢与 A 的子类一起工作并且尽可能自动化的解决方案。
谢谢!
您可以创建一个实体链接列表,其中每个实体有两个引用:一个指向其先前版本,一个指向下一个版本。当然,您必须自己维护这些引用。实体的最新版本将是没有对下一个版本的引用(或空/空引用)的实体。
根据您的用例,您可能还想研究仅存储实体的两个版本之间的差异的方法(如果更改很小而实体很大)。
我们正在为我们的 AppEngine 应用程序之一做类似的事情。我们发现的唯一有效方法是,拥有一个作为您的版本的实体 B,而实体 A 保留一个键列表。
然后,我们在 REST 服务中使用 ETags 来识别我们的客户端获得了哪个版本的副本。
有很多方法可以做到这一点。
如果您想要一种不需要数据模型中更多类的方法,您可以使用 parent 属性来编写版本和祖先查询,以便读取最新版本。
这是一个使用 Python GAE 中的 ndb.Model 和 webapp2 框架在 wiki 页面中如何工作的示例:
该模型可以是:
class WikiPage(ndb.Model):
title = ndb.StringProperty(required = True)
text = ndb.TextProperty(required = True)
datetime = ndb.DateTimeProperty(auto_add_now = True)
句柄可以是:
class Page(webapp2.RequestHandler):
def get(self, path):
# create the page key from the page id (in this case, the get request path)
page_key = ndb.Key('WikiPage', path)
# query for edited versions
wikipage_edited = WikiPage.query(ancestor=page_key).order(-WikiPage.datetime).get()
# check if wikipage have edited versions
if wikipage_edited:
wikipage = wikipage_edited
# if not, get the original version
else:
wikipage = page_key.get()
# some custom function to render the wikipage
self.render(wikipage)
def post(self):
# you can pass some parameter that indicates the page_id being edited
page_id = self.request.get('page_id')
# check if page_id was sent
if page_id:
wikipage = WikiPage(parent = ndb.Key('WikiPage', page_id),
title = self.request.get('new_title'),
text = self.request.get('new_text'))
# if page_id wasn't sent, it assumes that a new page is being created
else:
# some custom function that create a page id in the way you want
page_id = self.create_a_page_id()
wikipage = WikiPage(id = page_id,
title = self.request.get('title'),
text = self.request.get('text'))
wikipage.put()