无法使用 SqlAlchemy 腌制对象错误
Can't pickle object error using SqlAlchemy
我正在尝试使用 SqlAlchemy 将 mutable 对象存储在 postgresql 数据库中。对象的class大致为:
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))
每当我尝试向 table 添加一行(包括此列)时,我都会收到以下错误:
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
class 本身可以使用 Python 提示进行腌制;我可以毫无问题地 pickle.dumps
和 pickle.loads
实例。 Google 没有结果,我找不到任何相关的错误报告。
我正在使用 SqlAlchemy 1.0.13 和 Python 3.5。
从阅读 "Supporting Pickling" 看来,您必须至少为自定义可变类型提供 __getstate__
方法:
The developer responsibility here is only to provide a __getstate__
method that excludes the _parents()
collection from the pickle stream:
这是因为可变扩展在值对象上放置了一个 weakref.WeakKeyDictionary
,它不能被 pickle。文档中提供了一个最小的 __getstate__
实现:
class Data(Mutable, object):
...
def __getstate__(self):
d = self.__dict__.copy()
d.pop('_parents', None)
return d
根据您的类型的实现方式,您可能还必须提供 __setstate__
。
我正在尝试使用 SqlAlchemy 将 mutable 对象存储在 postgresql 数据库中。对象的class大致为:
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))
每当我尝试向 table 添加一行(包括此列)时,我都会收到以下错误:
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
class 本身可以使用 Python 提示进行腌制;我可以毫无问题地 pickle.dumps
和 pickle.loads
实例。 Google 没有结果,我找不到任何相关的错误报告。
我正在使用 SqlAlchemy 1.0.13 和 Python 3.5。
从阅读 "Supporting Pickling" 看来,您必须至少为自定义可变类型提供 __getstate__
方法:
The developer responsibility here is only to provide a
__getstate__
method that excludes the_parents()
collection from the pickle stream:
这是因为可变扩展在值对象上放置了一个 weakref.WeakKeyDictionary
,它不能被 pickle。文档中提供了一个最小的 __getstate__
实现:
class Data(Mutable, object):
...
def __getstate__(self):
d = self.__dict__.copy()
d.pop('_parents', None)
return d
根据您的类型的实现方式,您可能还必须提供 __setstate__
。