1

私はデータをモデリングしていますが、その 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 を取得する方法はありますか?

4

2 に答える 2

3

基本的にこれはできません。外部カウンター「シングルトン」が必要であり、1 秒あたり約 1 回以上の書き込みが必要な場合は、パフォーマンスのために共有を追加する必要があります。オプションの説明については、Google AppEngine で「自動インクリメント」を実装する方法を参照してください。

于 2012-05-13T13:11:16.590 に答える