I'm modelling data, which IDs should be with auto increment. Actually, I've made working model, but need some advise from datastore guru.
There is my code for ID generation:
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()
This code generates straightforward IDs, but I'm quite not sure is it good enough.
UPD: This code fails. Several entities can be written with same key and data can be overwritten.
№1. Can it cause problem with data loss? "While loop" preserves app from generating ID. But I'm not sure there is no possibility for data to be overwritten.
№2. May transaction like this make saving better?
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: Transaction helps to avoid data loss. This code seems to work much better than first example.
№3. Is there a way to get max ID from group of entities without extra field for index?