SQLAlchemy:コミット後にオブジェクトマッピングが失われますか?
-
06-07-2019 - |
質問
SQLAlchemyで簡単な問題が発生しました。テーブルに1つのモデルがあるので、ここでModel1と呼びます。 このテーブルに行を追加し、自動インクリメントキーを取得したいので、それを使用して別のモデルを作成し、このキーを使用できます。これは、欠陥のあるデータベース設計ではありません(1:1の関係など)。他のテーブルはリモートホストに転送されるため、このキーは別のテーブルで必要になります。サーバーが相互に理解できるように、一致するキーが必要です。これらの2つのテーブル間にローカル参照はありません。また、そのためリレーションを作成することもできません。
次のコードを検討してください:
object1 = model.Model1(param)
DBSession.add(object1)
# if I do this, the line below fails with an UnboundExecutionError.
# and if I dont do this, object1.id won't be set yet
#transaction.commit()
object2 = model.AnotherModel(object1.id) #id holds the primary, autoincremented key
「手動で」コミットする必要さえないことを望みました。 基本的に私が達成したいのは、「Model1」です。 Model.id主キーの増加に伴い、絶えず成長しています。 AnotherModelは常にModel1のほんの一部であり、まだ処理されていません。もちろん、既に処理済みの要素をマークするためにテーブルのブール型フィールドである「Model1」にフラグを追加することもできますが、これが不要になることを望んでいました。
上記のコードを機能させるにはどうすればよいですか
Greets、
トム
解決
いくつかのこと:
- 変数
transaction
のバインド先を説明してください - 正確には、UnboundExecutionErrorが発生するステートメントは何ですか?
- スタックトレースを含む完全な例外メッセージを提供してください。
- この場合の「通常の」ことは、
DBSession.flush()
を呼び出すことです。試しましたか?
例:
object1 = Model1(param)
DBSession.add(object1)
DBSession.flush()
assert object1.id != None # flushing the session populates the id
object2 = AnotherModel(object1.id)
SAセッションと flush()
の詳細については、セッションの使用。
基本的に、 flush()
により、保留中のインスタンスが永続的になります。つまり、新しいオブジェクトがデータベーステーブルに挿入されます。 flush()
は、セッションが変更を追跡するインスタンスの値でテーブルを更新します。
commit()
は常に flush()
を最初に発行します。
トランザクション内では、複数回フラッシュできます。各flush()により、データベースでUPDATEおよび/またはINSERTが発生します。トランザクション全体をコミットまたはロールバックできます。
他のヒント
何もコミットせずに生成する新しい主キー識別子を取得する場合は、session.flush()を呼び出します。これは、現在のトランザクション内でデータベースに保留中のすべてを発行します。
ForeignKeysでこれを使用しただけなので、2番目のケースでは、model.AnotherModel(model1 = object1)を使用し、それが機能しました(tm)。だから、これはあなたのモデルの問題かもしれないと思うので、おそらくあなたもそれらを投稿することができますか?