回答:
サンプルコードはそのままで機能するはずです。SQLAlchemyはf.id
、自動生成の主キー列を想定して、の値を提供する必要があります。主キー属性は、生成されるとすぐにflush()
プロセス内に入力され、への呼び出しはcommit()
必要ありません。したがって、ここでの答えは次の1つ以上にあります。
私はちょうど同じ問題に出くわしました、そしてテストの後、これらの答えのどれも十分ではないことがわかりました。
現在、またはsqlalchemy .6以降では、非常に単純な解決策があります(これが以前のバージョンに存在するかどうかはわかりませんが、あると思います)。
session.refresh()
したがって、コードは次のようになります。
f = Foo(bar=x)
session.add(f)
session.flush()
# At this point, the object f has been pushed to the DB,
# and has been automatically assigned a unique primary key id
f.id
# is None
session.refresh(f)
# refresh updates given object in the session with its state in the DB
# (and can also only refresh certain attributes - search for documentation)
f.id
# is the automatically assigned primary key ID given in the database.
それはそれを行う方法です。
sessionmaker(autoflush=True)
。そのコンボw / refresh()によって行IDが提供されました。#grrr
flush()
使用する代わりに、そのcommit()
直後に-で更新しsession.refresh(f)
、私のために機能し、SQLAlchemyバージョンを使用します0.6.7
dpbの答えとは異なり、更新は必要ありません。フラッシュしたら、idフィールドにアクセスできます。sqlalchemyは、バックエンドで自動生成されたIDを自動的に更新します。
私はこの問題に遭遇し、いくつかの調査の後に正確な理由を理解しました。私のモデルは整数フィールドとしてIDで作成され、私のフォームではIDは非表示フィールドで表されていました(フォームにIDを表示したくなかったため)。非表示フィールドは、デフォルトではテキストとして表されます。widget = hiddenInput())を使用してフォームをintegerfieldに変更すると、問題は解決しました。
のsession.save_or_update(f)
代わりに使用してみてくださいsession.add(f)
。
save_or_update
0.5以降で廃止されました。session.add()
それを行う必要があります。
echo=True
で初期化して、フラッシュ時に実行されるSQLを確認できますか?あなたが説明したことは機能し、あなたにidを与えるはずですが、f.idがNoneになる他の問題があるかもしれません。