2013-01-31 17 views
18

ormを使用してSQLAlchemyでモデルインスタンス(行)を複製したいとします。私が最初に考えたのは、これを行うことでした。SQLAlchemy:分離オブジェクトの変更

i = session.query(Model) 
session.expunge(i) 

old_id = i.id 
i.id = None 
session.add(i) 
session.flush() 
print i.id #New ID 

しかし、明らかに分離オブジェクトはまだ、それが外れた間、私はなしにIDを設定していても、持っていたものID「記憶します」。したがって、session.flush()は、主キーをnullに変更するUPDATEを実行しようとします。

これが期待どおりの動作ですか?この属性の 'メモリ'を削除するにはどうしたら、デタッチしたオブジェクトをセッションに再追加する際に新しいオブジェクトとして扱うことができますか?一般に、SQLAlchemyモデルインスタンスをどのようにクローンしますか?

答えて

34

この場合はmake_transient()ヘルパー関数を使用して提供されています:

inst = session.query(Model).first() 
session.expunge(inst) 

make_transient(inst) 
inst.id = None 
session.add(inst) 
session.flush() 
print inst.id #New ID 
+0

おかげで、ドキュメントでそれを見ていません。 –

+4

関係をコピーする適切な方法は@zzzeekですか? – jmagnusson

+0

私も似たようなものに興味があります。私は、エンティティ(行)と、そのすべての「子」エンティティ(この行を指す外部キーを持つ他のテーブルの行)と一緒にクローン作成し、この新しい複製行とその重複子を新しい親エンティティ新しい重複行の異なる外部キーを使用して(ただし、既存のエンティティとその子エンティティには影響を与えません)。私はこの部分的な答えをSOの別の質問で見ることができます:http://stackoverflow.com/questions/20112850/sqlalchemy-clone-table-row-with-relations?lq=1 – Soferio

1
def duplicate(self): 
    arguments = dict() 
    for name, column in self.__mapper__.columns.items(): 
     if not (column.primary_key or column.unique): 
      arguments[name] = getattr(self, name) 
    return self.__class__(**arguments) 
+0

オブジェクトが「保留中」の場合、これは実行されません関係はありません。私。外部キー列はまだ入力されていません。 – gromgull

+0

メソッドとハイブリッド属性もコピーしません。 – Jakobovski

関連する問題