2009-06-23 8 views
2

私はSQLAlchemyで簡単な問題があります。私はテーブルの中に1つのモデルを持っています、ここでそれをModel1と呼ぶことができます。 このテーブルに行を追加し、自動インクリメントキーを取得したいので、別のモデルを作成してこのキーを使用できます。これは、欠陥のあるデータベース設計(1:1関係など)ではありません。他のテーブルがリモートホストに転送されているので、このキーが別のテーブルに必要になります。サーバーが互いに理解できるように、一致するキーが必要です。これらの2つのテーブルの間には、それ以上のローカル参照はなく、そのために関係を作成することもできません。私は、私も「手動」にコミットする必要はありません願っSQLAlchemy:コミット後にオブジェクトマッピングが失われる?

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 

は、次のコードを考えてみましょう。 基本的に私が達成したいのは、Model1idのプライマリキーを増やすことで、 "Model1"が絶えず増加していることです。 AnotherModelは、まだ処理されていないModel1のほんの一部です。もちろん、すでに処理された要素をマークするためにテーブルのブール値フィールドである "Model1"にフラグを追加することもできますが、これは必要ではないと考えていました。

上記のコードはどのように動作させることができますか?

挨拶し、

トム

答えて

3

物事のカップル:

  • あなたは変数transactionがバインドされているかを説明してもらえますか?
  • UnboundExecutionErrorをどのような声明で提起しますか?
  • スタックトレースを含む完全な例外メッセージを入力してください。
  • この場合、「通常の」ことは、DBSession.flush()を呼び出すことです。あなたはそれを試しましたか?

例:SAセッションと何flush()Using the Sessionを見んと偉大な説明については

object1 = Model1(param) 
DBSession.add(object1) 
DBSession.flush() 
assert object1.id != None # flushing the session populates the id 

object2 = AnotherModel(object1.id) 

基本的にflush()は、保留中のインスタンスを永続化します。つまり、新しいオブジェクトがデータベーステーブルにINSERTされます。 flush()また、セッションが変更を追跡するインスタンスの値を持つテーブルを更新します。

commit()は常にflush()を発行します。

トランザクション内では、複数回フラッシュすることができます。各flush()は、データベース内のUPDATEおよび/またはINSERTを引き起こします。トランザクション全体をコミットまたはロールバックできます。

+0

object2 = AnotherModel(object1.id)<= object1.idはありませんまだデータベースにコミットされていないため、このIDはまだ入力されていないため、バインドされていません。 はい、SAドキュメントの長い夜の後、私は本当に助けとなったフラッシュ物を見つけました。私はまだフラッシュとコミットの違いを知らない。

このスレッドも http://stackoverflow.com/questions/620610/sqlalchemy-obtain-primary-key-with-autoincrement-before-commitより正確に、それはもう少し明確 – Tom

+0

おかげで、私の元の問題を説明し、私はまだcommit()とflush()の間に本当の違いは見当たりません。それは明確に記述されていません。今私はSAを読んでいる両方のページで、それはC&Fの両方がDBにオブジェクトを保持していると言います。なぜ2のコマンドの冗長性はそれからですか?しかし、ポインタのおかげで、私はあなたの答えをもう一度upvoteできます:) – Tom

+0

トランザクションはTurboGearのトランザクションマネージャにバインドされています。 – ebo

1

第2のケースであなたはかなりmodel.AnotherModel(MODEL1 =オブジェクト1)だろうので、私は、のForeignKeyでこれだけ使ってきたし、それだけで(TM)を働きました。だから私はこれがあなたのモデルの問題かもしれないと思うので、あなたもそれらを投稿することができますか?

+0

私は上に述べたように、私のテーブルは台無しになっていません。これは設計上の問題ではありません。基本的には1:1の関係です。しかし、最終的にはテーブルのコピーだけで、私はXMLRPCを別のサーバーに、実際にはローカルの1:1の関係にはしません。興味のない、私はあなたの方法を試みますが、私のものは、フラッシュのおかげで、現在の仕事は、うまくいけば、私の好奇心があります:) – Tom

2

新しいプライマリキー識別子をコミットせずに生成させたい場合は、単にsession.flush()を呼び出します。これは、現在のトランザクション内でデータベースに保留中のすべてを発行します。

関連する問題