2017-10-05 4 views
0

したがって、1対多の関係に2つのテーブルがあります。 Table1の新しい行を作成するときに、Table2に関連する行を設定したいとします。しかし、この集団は、実際には、他の関連テーブルのデータを使用してTable2の行を計算することが必要です。関連するテーブルをSqlAlchemyに配置するORM

ORMレイヤーを使用してこれを行うにはどうすればよいでしょうか?つまり、ORMを通じてTable1マッピングが作成されていると仮定すると、どこで/どのようにコードを作成してTable2を配置する必要がありますか?

私はafter_insertフックを使用することを考えましたが、私は集団メソッドに渡すセッションを持っています。

ありがとうございました。

+0

何を試しましたか? – AndMar

+0

本当に難しいと思っています。 '__init__'メソッドのマッピングは、オブジェクトがセッション/トランザクションに入る前と同じです。私はsqlalchemyのさまざまなフックを調べました。 'after_insert'はあなたにセッションではなく接続を与えます。私の人口コードはセッションが必要です。同等のフックがありますが、セッションにはありますか? –

答えて

0

#sqlalchemy IRCで質問したところ、before_flushイベントリスナーでORMレベルの関係を使用してこれを行うことができました。

リレーションシップを使用してマッピングを追加すると、外部キーが自動的にフラッシュされ、適切な挿入ステートメントがORMによって生成されることが説明されています。

1

before_flushまたはafter_flushhookは、sessionです。新しく作成されたモデル(isinstance(object, ModelClass)を使用)のsession.newオブジェクトをチェックして、ここで作業してください。

実際、SQLAlchemy recommendsbefore_flushは一般的なフラッシュ変更です。

マッパー・レベルのフラッシュ・イベントは、限られた操作しか行えず、操作対象の行のローカル属性のみで、指定されたConnectionでSQLを発行できるようにします。これらのメソッドの使用に関するガイドラインについては、Mapperレベルのイベントのノートをすべて読んでください。一般的には、一般的なon-flushの変更にはSessionEvents.before_flush()メソッドを優先する必要があります。

+0

私はそんなことを考えましたが、すべての作成されたオブジェクトに対してisinstanceチェックを実行することは、すべてのフラッシュイベントを除いて、非常に非効率的でした。私はこれが唯一の方法ではないことを望んだ。私がしたいことは共通のパターンでなければならないと私は思っています。これは本当に一般的に何が行われているのですか? –

+0

これは、SqlAlchemyが推奨するとおりです。この分離されたケースから判断すると「非効率的」に見えるかもしれませんが、より高いレベルでは将来、他のモデルのカスタムハンドラが必要になる可能性があります。 catch-allのbefore_flushを実装し、個々のモデルクラス(特定のクラスの複数の 'before_flush')に対して特定のハンドラにリルートします。 「isinstance」は私の経験に基づいてあなたのボトルネックになる可能性は低いです。 –

+0

"pending_to_persistant"のような他のセッションイベントはどうですか?これはフラッシュ後のイベントで、ロールバックできないことを意味しますか? –

関連する問題