Как сохранить историю версий сущностей хранилища данных в Appengine - PullRequest
8 голосов
/ 05 июня 2011

Я храню Entity A в моем хранилище данных на appengine. А имеет идентификатор типа Long. Я хотел бы сохранить историю всех изменений, внесенных в поля А. Каковы лучшие практики для создания версий этого типа на объектах? Я бы предпочел решение, которое хорошо работает с подклассами A и максимально автоматизировано.

Спасибо!

Ответы [ 3 ]

2 голосов
/ 05 июня 2011

Вы можете создать связанный список сущностей, где каждая сущность имеет две ссылки: одну на свою предыдущую версию и одну на следующую версию.Вы должны поддерживать эти ссылки самостоятельно, конечно.Самой последней версией сущности будет та, которая не имеет ссылки на следующую версию (или пустая / нулевая ссылка).

В зависимости от вашего варианта использования вы можете также рассмотреть способы сохранения различий только между двумя версиями объекта (если изменения небольшие и объекты большие).

0 голосов
/ 30 января 2014

Есть много способов сделать это.

Если вы хотите один способ, который не требует большего количества классов в модели данных, вы можете использовать родительский атрибут для записи версий и запроса предка, чтобы прочитать последнюю версию.

Вот пример того, как это может работать на вики-странице с использованием инфраструктуры ndb.Model и webapp2 в Python GAE:

Модель может быть:

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()
0 голосов
/ 05 июня 2011

Мы делаем нечто подобное для одного из наших приложений AppEngine. Единственный эффективный способ, который мы нашли, - это иметь объект B, который является вашей версией, и объект A хранит список ключей.

Затем мы используем ETags в наших службах REST, чтобы определить, какую версию получает наш клиент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...