【问题标题】:Can't pickle object error using SqlAlchemy无法使用 SqlAlchemy 腌制对象错误
【发布时间】:2016-07-14 14:59:00
【问题描述】:

我正在尝试使用 SqlAlchemy 将可变对象存储在 postgresql 数据库中。对象的类大致是:

class Data(Mutable, object):
    @classmethod
    def coerce(cls, key, value):
        return value

    def __init__(self, foo, bar):
        self._foo = foo     # foo is an array of short strings
        self._bar = bar     # bar is a single short string

    def append_to_foo(self, baz):
        self._foo.append(baz)
        self.changed()

    # Various other methods for mutating/accessing foo and bar, which call self.changed()
    # when they finish

列定义为:

data = Column(Data.as_mutable(PickleType))

每当我尝试向包含此列的表中添加一行时,都会收到以下错误:

sqlalchemy.exc.StatementError: (builtins.AttributeError) Can't pickle local object 'WeakKeyDictionary.__init__.<locals>.remove' [SQL: "INSERT INTO table (id, user_id, data) VALUES (nextval('data_id_seq'), %(user_id)s, %(data)s) RETURNING data.id"] [parameters: [{'data': <mypkg.foo.Data object at 0x7f79b3b52c88>, 'user_id': 36}]]

我已经确保 Data 类本身可以使用 Python 提示符进行腌制;我可以pickle.dumpspickle.loads 实例没有问题。 Google 没有产生任何结果,我也找不到任何相关的错误报告。

我正在使用 SqlAlchemy 1.0.13 和 Python 3.5。

【问题讨论】:

标签: python sqlalchemy pickle


【解决方案1】:

从阅读"Supporting Pickling" 看来,您必须至少为自定义可变类型提供__getstate__ 方法:

这里的开发者职责只是提供一个__getstate__ 方法,从pickle 流中排除_parents() 集合:

这是因为可变扩展在值对象上放置了一个weakref.WeakKeyDictionary,它不能被腌制。文档中提供了一个最小的__getstate__ 实现:

class Data(Mutable, object):

    ...

    def __getstate__(self):
        d = self.__dict__.copy()
        d.pop('_parents', None)
        return d

根据您的类型的实现方式,您可能还必须提供__setstate__

【讨论】:

    猜你喜欢
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 2018-10-18
    相关资源
    最近更新 更多