2012-04-24 58 views
0

我正在對數據進行建模,該ID應該與自動增量一起使用。實際上,我已經制定了工作模型,但需要來自數據存儲大師的建議。App引擎數據存儲區:使用NDB的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?

+2

在分佈式系統上創建順序標識符時很難避免競爭條件,我不認爲你的第一個例子成功。至少你將需要涉及一個事務(儘管我不確定你的第二個例子是否可用。)(另請參閱http://stackoverflow.com/questions/3985812/how-to-implement- autoincrement-on-google-appengine雖然可能ndb改變了事情,所以我還沒有投票結束重複)。 – geoffspear 2012-04-24 11:44:03

+1

你爲什麼(認爲你)需要順序ID?數據存儲帶有一個非常令人滿意的方式來生成_unique_ IDs。 – 2012-04-27 04:25:28

回答

0

對自己排序沒有意義class .entity_id字段beacuse這個字段是一個唯一的標識符,從來沒有增量值,沒有任何添加的意義。