4

特定の SQLAlchemy マップされたクラスをオーバーライド__deepcopy__して、SQLA 属性を無視し、クラスの一部である他のすべてをディープコピーしたいと考えています。

特に Python の組み込みオブジェクトをオーバーライドすることには特に詳しくありませんが、何が必要かについてはある程度の考えがあります。

UserSQLA を使用してマップされる非常に単純なクラスを作成しましょう。

class User(object):
    def __init__(self, user_id=None, name=None):
        self.user_id = user_id
        self.name = name

dir()マッピングの前後に、どの SQLAlchemy 固有の属性があるかを確認していましたが_sa_class_manager_sa_instance_state.

Questions
それらが唯一のものである場合、定義するときにそれをどのように無視し__deepcopy__ますか?
また、SQLA がマップされたオブジェクトに挿入する属性はありますか?


(私は以前の質問でこれを尋ねました(ただし、主な質問への回答を選択した数日後の編集として)が、そこで電車に乗り遅れたと思います。そのことをお詫びします。)


Edit - Fixed code thanks to zifot's answer

memo私が Python ドキュメントから得た唯一のことは、追加の引数としてdeepcopy を定義する必要があるということです。少し掘り下げた後、私はこれを試しました:

def __deepcopy__(self, memo):
    dpcpy = self.__class__()
    memo[id(self)] = dpcpy
    for attr in dir(self):
        if not attr.startswith('_'):
            value = getattr(self, attr)
            setattr(dpcpy, attr, copy.deepcopy(value, memo))
    return dpcpy

次に、次のようにインスタンスを作成しましたUser

snake = User(913, 'Snake,S.')  

その後、次のようにdeepcopy操作 を試みました。

snake_dc = copy.deepcopy(snake)

...そしてsnake_dcまだSQLA属性が含まれています...

私はすべて、助け、提案などを受け入れます。

4

4 に答える 4

1

mavnnは正しいです。たとえば、ユーザーの init を次のように変更してみてください。

def __init__(self, user_id = None, name = None):
        self.user_id = user_id
        self.name = name

マップされたインスタンスのコピーについては、このスレッドを読むことをお勧めします

于 2010-06-14T12:08:46.657 に答える
0

私はディープコピーの専門家ではありませんが、エラーから、パラメーターself.__class__()なしで呼び出すにはパラメーターなしのコンストラクターが必要なようです。

于 2010-06-14T11:59:23.463 に答える
0

sqlalchemy 列とマップされた属性を除外するには、次のようにします。

for attr in dir(self):
    if not self._sa_class_manager.mapper.has_property(key):
        ...
于 2010-06-14T23:07:49.127 に答える