Я моделирую данные, идентификаторы которых должны быть с автоматическим приращением. На самом деле, я создал рабочую модель, но мне нужно дать совет от гуру хранилища данных.App Engine datastore: ID auto increment with NDB
Существует мой код для генерации ID:
class AutoIncrementModel(ndb.Model):
entity_id = ndb.IntegerProperty('eID')
def _pre_put_hook(self):
if self.key and self.key.id(): return
latest = self.__class__.query().order(-self.__class__.entity_id).get()
self.entity_id = latest and latest.entity_id + 1 or 1
while self.__class__.get_by_id(self.entity_id): self.entity_id += 1
self.key = ndb.Key(self.__class__.__name__, self.entity_id, parent=self.key and self.key.parent() or None)
self.put()
Этот код генерирует простые идентификаторы, но я совсем не уверен, что это достаточно хорошо.
UPD: Этот код не работает. Несколько объектов могут быть записаны с одним ключом, и данные могут быть перезаписаны.
№1. Может ли это вызвать проблему потери данных? «While loop» сохраняет приложение от генерации идентификатора. Но я не уверен, что нет возможности перезаписи данных.
№2. Может ли такая транзакция лучше экономить?
def _pre_put_hook(self):
def callback():
while self.__class__.get_by_id(self.entity_id): self.entity_id += 1
self.key = ndb.Key(self.__class__.__name__, self.entity_id, parent=self.key and self.key.parent() or None)
self.put()
if self.key and self.key.id(): return
latest = self.__class__.query().order(-self.__class__.entity_id).get()
self.entity_id = latest and latest.entity_id + 1 or 1
ndb.transaction(callback, xg=True)
UPD: Сделка помогает избежать потери данных. Этот код работает намного лучше, чем первый пример.
№3. Есть ли способ получить максимальный ID из группы объектов без дополнительного поля для индекса?
Трудно избежать состояния гонки при создании последовательных идентификаторов в распределенной системе, и я не думаю, что ваш первый пример преуспевает в этом. По крайней мере, вам потребуется задействовать транзакцию (хотя я не уверен, работает ли ваш второй пример.) (Также см. Http://stackoverflow.com/questions/3985812/how-to-implement- autoincrement-on-google-appengine, хотя возможно, что ndb меняет вещи, поэтому я не проголосовал за закрытие как дубликат). – geoffspear
Почему вы (думаете, что вам) нужны последовательные идентификаторы? Хранилище данных имеет вполне удовлетворительный способ генерации _unique_ ID. –