【问题标题】:Consistent indexing for objects with variable attributes in ZODBZODB 中具有可变属性的对象的一致索引
【发布时间】:2012-09-27 23:43:27
【问题描述】:

我有一个 ZODB 安装,我必须在其中组织几百万个大约几种不同类型的对象。我有一个通用容器类Table,它包含 BTree,用于按属性或这些属性的组合索引对象。数据一致性非常重要,因此我想强制执行,当我写入索引覆盖的任何属性时,索引会自动更新。所以一个简单的obj.a = x 应该足以计算所有新的依赖索引条目,检查是否有任何冲突,最后写入索引和值。

总的来说,我很乐意为此使用库,因此我查看了 repoze.catalogIndexedCatalog,但对此并不满意。 IndexedCatalog 似乎已经死了很长一段时间,并且没有为对象的更改提供那种一致性。据我所知, repoze.catalog 似乎更常用和更活跃,但也没有提供这种一致性。如果我在这里遗漏了什么,我很乐意听到它,并且更喜欢重用而不是重新发明。

所以,除了试图为问题找到一个库之外,我如何看待它,我必须使用描述符拦截对数据对象属性的写访问,并让Table 类发挥改变索引的魔力。为此,描述符实例必须知道它们必须与哪些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。有没有更优雅的方式?保留描述符本身?欢迎任何建议和最佳实践示例!

【问题讨论】:

    标签: python indexing consistency zodb


    【解决方案1】:

    所以我终于弄清楚了自己。解决方案分为三个部分。不需要丑陋的单身人士。 Table 提供了检查冲突的逻辑,DatabaseElement 能够查找负责的Table 而没有丑陋的解决方法,Property 负责在写入任何索引值之前更新索引。这里有一些sn-ps,主要线索是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)
    

    【讨论】:

      猜你喜欢
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 2021-07-23
      • 1970-01-01
      相关资源
      最近更新 更多