如何在Appengine中保留数据存储区实体的版本历史记录

时间:2011-06-05 00:23:36

标签: database google-app-engine versioning datastore

我正在我的数据存储中将实体A存储在appengine上。 A的ID为Long。我想保留A字段所做的所有更改的历史记录。在实体上进行此类版本的最佳做法是什么?我更喜欢一种适用于A的子类并且尽可能自动化的解决方案。

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以创建实体的链接列表,其中每个实体都有两个引用:一个引用其先前版本,另一个引用下一个版本。当然,你必须自己维护这些引用。实体的最新版本将是不引用下一版本(或空/空引用)的实体。

根据您的使用情况,您可能还想查看仅存储两个版本实体之间差异的方法(如果更改很小且实体很大)。

答案 1 :(得分:0)

我们正在为我们的某个AppEngine应用做类似的事情。我们找到的唯一有效方法是,有一个实体B是您的版本,实体A保留一个键列表。

然后,我们在REST服务中使用ETag来识别客户端获取副本的版本。

答案 2 :(得分:0)

有很多方法可以做到这一点。

如果您想要一种在数据模型中不需要更多类的方法,可以使用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()