2

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」にフラグを追加して、すでに処理された要素をマークすることもできますが、これは必要ないことを望んでいました。

上記のコードを機能させるにはどうすればよいですか?

挨拶、

トム

4

3 に答える 3

3

いくつかのこと:

  • 変数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が発生します。トランザクション全体をコミットまたはロールバックできます。

于 2009-06-23T21:24:34.307 に答える
2

何もコミットせずに生成する新しい主キー識別子を取得する場合は、session.flush()を呼び出すだけです。これにより、現在のトランザクション内でデータベースに保留中のすべてのものが送信されます。

于 2009-06-25T01:29:33.067 に答える
1

私はこれをForeignKeysでのみ使用したので、2番目のケースではむしろmodel.AnotherModel(model1 = object1)を実行し、それでうまくいきました(tm)。だから、これはあなたのモデルに問題があるのではないかと思うので、あなたもそれらを投稿することができますか?

于 2009-06-23T19:20:17.367 に答える