2012-09-27 1 views
2

몇 가지 유형의 객체 만 몇 개씩 구성해야하는 ZODB 설치가 있습니다. 일반적인 컨테이너 클래스 Table, 특성 또는 이러한 특성의 조합으로 개체를 인덱싱하는 BTrees 포함되어 있습니다. 데이터 일관성은 매우 중요하므로 인덱싱에서 다루는 특성 중 하나에 쓸 때 색인이 자동으로 업데이트되도록 시행하고 싶습니다. 따라서 간단한 obj.a = x은 모든 새로운 종속 색인 항목을 계산하고, 충돌이 없는지 확인하고, 마지막으로 색인과 값을 기록하기에 충분해야합니다.ZODB에서 변수 속성이있는 객체에 대한 일관된 색인 생성

일반적으로 라이브러리를 사용하면 기꺼이 repoze.catalogIndexedCatalog을 보았지만 실제로 만족스럽지 않았습니다. IndexedCatalog는 꽤 오래 동안 죽었으며 개체 변경에 일관성을주지 못합니다. repoze.catalog는 더 많이 사용되고 활발한 것처럼 보이지만, 내가 이해하는 한 이러한 종류의 일관성을 제공하지 않습니다. 여기에 뭔가 빠뜨린 경우, 그 사실을 듣고 재발용하는 것을 더 좋아할 것입니다.

그렇다면 문제의 라이브러리를 찾으려는 것 외에도 descriptor가있는 dataobject 속성에 대한 쓰기 액세스를 가로 채고 Table 클래스에서 인덱스를 변경하는 마법을 수행해야합니다. 이를 위해 설명자 인스턴스는 알고 있어야하며 Table 인스턴스와 대화해야합니다. 현재 구현가 someting 그렇게 간다 :이 DatabaseElement 클래스가 생성 될 때, 데이터베이스 내의 객체는 아직

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) 

를 생성되지 않습니다. 그래서이 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)