2016-07-13 7 views
2

SqlAlchemyを使用してpostgresqlデータベースに可変オブジェクトを格納しようとしています。オブジェクトのクラスは、おおよそ次のとおりです。SqlAlchemyを使用してオブジェクトエラーをpickleできません

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プロンプトを使ってpickleableであることを確認しました。 pickle.dumpspickle.loadsのインスタンスは問題ありません。 Googleでは結果が得られず、関連するバグレポートを見つけることができませんでした。

私はSqlAlchemy 1.0.13とPython 3.5を使用しています。 "Supporting Pickling"読んでから

+0

あなたはhttp://docs.sqlalchemy.org/en/latest/orm/extensions/mutable.html#supporting-picklingを読んでいますか?あなたは '__getstate__'を提供する必要があります。 –

+0

はい、それでした - 私は '__setstate__'も提供しなければなりませんでした。私はそれを受け入れることができるように答えを出すことができますか? – zrneely

答えて

3

は、あなたがカスタム可変タイプのために少なくとも__getstate__方法を提供しなければならないと思われる:

The developer responsibility here is only to provide a __getstate__ method that excludes the _parents() collection from the pickle stream:

変更可能な拡張が漬けすることができない値オブジェクト、時weakref.WeakKeyDictionaryを置くためです。最小限の__getstate__実装は、マニュアルに記載されています

class Data(Mutable, object): 

    ... 

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

あなたのタイプがあなたにも__setstate__を提供する必要があり実装されている方法に応じて。

関連する問題