2012-09-27 78 views
2

我有一個ZODB安裝,我必須組織好幾百萬個關於幾種不同類型的對象。我有一個通用容器類Table,其中包含BTrees通過屬性或這些屬性的組合對對象進行索引。數據一致性是非常重要的,所以我想強制執行,當我寫入任何屬於索引的屬性時,索引會自動更新。因此,一個簡單的obj.a = x應該足以計算所有新的從屬索引條目,檢查是否有任何衝突,最後寫入索引和值。ZODB中具有可變屬性的對象的一致索引

總的來說,我很樂意爲此使用一個庫,所以我在尋找repoze.catalogIndexedCatalog,但是對此並不滿意。 IndexedCatalog似乎已停用了一段時間,並沒有爲對象的更改提供一致性。據我所知,repoze.catalog似乎更加使用和活躍,但也沒有提供這種一致性。如果我在這裏錯過了一些東西,我很樂意聽到它,並且喜歡重複使用。

所以,除了試圖找到問題的庫之外,我不得不攔截對描述符的數據對象屬性的寫入訪問,並讓類改變索引的神奇。爲此,描述符實例必須知道,他們必須與哪個Table實例交談。當前實現成纔去這樣的:

class DatabaseElement(Persistent): 
    name = Property(constant_parameters) 
    ... 

class Property(object): 
    ... 
    def __set__(self, obj, name, val): 
     val = self.check_value(val) 
     setattr(obj, '_' + name, val) 

當生成這些DatabaseElement類,數據庫和內對象尚未創建。所以正如在nice answer中提到的那樣,我可能必須創建一些單例查找機制來查找Table對象,而無需將它們作爲實例化參數傳遞給Property。有沒有更優雅的方式?堅持描述符本身?任何建議和最佳實踐示例歡迎!

回答

0

所以我終於想通了自己。該解決方案分爲三部分。沒有醜陋的單身人士需要。 Table提供了邏輯檢查碰撞,DatabaseElement得到查找負責Table沒有醜陋的解決方法和Property照顧的能力,該指標被更新,被寫入任何索引值之前。這裏有一些片段,主要線索是DatabaseElement的表格查找。我也沒有看到在任何地方記錄。不錯的額外:它不僅驗證寫入單個值,我還可以一次檢查多個索引值的更改。

class Table(PersistentMapping): 
    .... 
    def update_indices(self, inst, updated_values_dict): 
     changed_indices_keys = self._check_collision(inst, updated_values_dict) 
     original_keys = [inst.key(index) for index, tmp_key in changed_indices_keys] 
     for (index, tmp_key), key in zip(changed_indices_keys, original_keys): 
      self[index][tmp_key] = inst 
      try: 
       del self[index][key] 
      except KeyError: 
       pass 


class DatabaseElement(Persistent): 
    .... 
    @property 
    def _table(self): 
     return self._p_jar and self._p_jar.root()[self.__class__.__name__] 

    def _update_indices(self, update_dict, verify=True): 
     if verify: 
      update_dict = dict((key, getattr(type(self), key).verify(val)) 
           for key, val in update_dict.items() 
           if key in self._key_properties) 
     if not update_dict: 
      return 
     table = self._table 
     table and table.update_indices(self, update_dict) 


class Property(object): 
    .... 
    def __set__(self, obj, val): 
     validated_val = self.validator(obj, self.name, val) 
     if self.indexed: 
      obj._update_indices({self.name: val}, verify=False) 
     setattr(obj, self.hidden_name, validated_val) 
相關問題