腌制对象版本控制

Posted

技术标签:

【中文标题】腌制对象版本控制【英文标题】:Pickled Object Versioning 【发布时间】:2011-01-22 14:23:42 【问题描述】:

我正在处理一个项目,我们有大量对象被序列化并使用pickle/cPickle 存储到磁盘。

随着项目生命周期的推进(在向现场客户发布后),未来的功能/修复可能会要求我们更改一些持久对象的签名。这可能是添加字段、删除字段,甚至只是更改一条数据的不变量。

是否有标准的方法来标记将被腌制为具有特定版本的对象(如 Java 中的serialVersionUID)?基本上,如果我正在恢复 Foo 版本 234 的实例,但当前代码是 236,我希望收到一些关于 unpickle 的通知。我是否应该继续推出自己的解决方案(可能是 PITA)。

谢谢

【问题讨论】:

【参考方案1】:

pickle 格式没有这样的附带条件。你为什么不把“序列号”作为对象属性的一部分,和其他的一起腌制呢?然后可以通过比较实际版本和所需版本来轻松获得“通知”——不明白为什么它应该是 PITA。

【讨论】:

是的,这就是我认为我们将要采取的方向。我想我可能高估了添加和检查这些数据所需的工作量。由于我们在一个地方恢复了所有保存的状态,因此添加我们需要的任何逻辑(处理未版本化的对象或以前未版本化但现在的对象应该不会太糟糕)。尽管我会 ping 社区以查看 pickle 是否提供了这种行为并且我正在重新发明***。【参考方案2】:

考虑以下由 Tomasz Früboes here 建议的类 mixin。

# versionable.py
class Versionable(object):
    def __getstate__(self):
        if not hasattr(self, "_class_version"):
            raise Exception("Your class must define _class_version class variable")
        return dict(_class_version=self._class_version, **self.__dict__)
    def __setstate__(self, dict_):
        version_present_in_pickle = dict_.pop("_class_version")
        if version_present_in_pickle != self._class_version:
            raise Exception("Class versions differ: in pickle file: , "
                            "in current class definition: "
                            .format(version_present_in_pickle,
                                    self._class_version))
        self.__dict__ = dict_

__getstate__ 方法在酸洗时被pickle 调用,__setstate__ 在解酸时被pickle 调用。这个混合类可以用作您要跟踪其版本的类的子类。这将按如下方式使用:

# bla.py
from versionable import Versionable
import pickle

class TestVersioning(Versionable):
    _class_version = 1

t1 = TestVersioning()

t_pickle_str = pickle.dumps(t1)

class TestVersioning(Versionable):
    _class_version = 2

t2 = pickle.loads(t_pickle_str) # Throws exception about wrong class version

【讨论】:

效果很好,谢谢!您的链接 (Tomasz Früboes) 已损坏。 我编辑了链接以指向该网站的存档(历史)版本。

以上是关于腌制对象版本控制的主要内容,如果未能解决你的问题,请参考以下文章

实现数据库对象的版本控制

具有多级嵌套关系版本控制的对象

pickle.dump(模型,pickle_out)| TypeError:无法腌制 _thread._local 对象

在哪里可以找到有关 Core Data 对象模型版本控制和迁移的更多详细信息?

版本控制如何与 Flex 远程对象和 AMF 一起使用?

[.net 面向对象程序设计进阶] (25) 团队开发利器分布式版本控制系统Git (上)