私はデータをモデリングしていますが、その ID は自動インクリメントである必要があります。実際、動作するモデルを作成しましたが、データストアの第一人者からのアドバイスが必要です。
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()
このコードは単純な ID を生成しますが、これで十分かどうかはよくわかりません。
UPD :このコードは失敗します。複数のエンティティを同じキーで書き込み、データを上書きできます。
№1。データ損失の問題を引き起こす可能性はありますか? 「while ループ」は、アプリが ID を生成しないようにします。しかし、データが上書きされる可能性がないかどうかはわかりません。
№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 を取得する方法はありますか?