2011-12-21 13 views
6

私はちょっと厄介な問題を抱えて実行しました。テストの結果、利用可能な回答のうちのどれもが十分ではないことがわかりました。SQLAlchemyを使用してMySQLから最後に挿入された値を取得

私はさまざまな提案を見てきましたが、MySQLのauto_incrementフィールドの最後に挿入された値を返すことができないようです。

私は、レコードを追加してidを取得するためにsession.flush()を使用する例を見てきました。しかし、いつも私もsession.refresh(の使用はもちろんの例を見てきました0

返すようです)が、それは次のエラーを発生させている:InvalidRequestErrorを:インスタンス「」私は何

を更新できませんでしたやってみると非常にシンプルに思えるが、私はその秘密を理解できないようだ。

私は宣言的なアプローチを使用しています。オブジェクトfは、DBにプッシュされており、自動的に一意の主キーのIDが割り当てられている、この時点で

class Foo(Base): 
    __tablename__ = 'tblfoo' 
    __table_args__ = {'mysql_engine':'InnoDB'} 

    ModelID = Column(INTEGER(unsigned=True), default=0, primary_key=True, autoincrement=True) 
    ModelName = Column(Unicode(255), nullable=True, index=True) 
    ModelMemo = Column(Unicode(255), nullable=True) 

f = Foo(ModelName='Bar', ModelMemo='Foo') 
session.add(f) 
session.flush() 

だから、私のコードは次のようになります。しかし、私は、いくつかの追加の操作で使用する値を取得する方法を見つけることができないようです。私は、次の操作を実行したいと思います:

my_new_id = f.ModelID

私は単に他のパラメータに基づいてModelIDをルックアップするために別のクエリを実行することができるが、すべての可能であれば私がいないことを好むだろう知っています。

私は、この問題の解決策について何らかの洞察を深めることができます。

ご協力ありがとうございます。

答えて

9

問題は、自動インクリメントにdefaulを設定していることです。それは、クエリへの挿入を実行するときに、サーバーのログには、だから、出力がデフォルト値であり、あなたがautoincrement列のデフォルト値を設定しているので、渡された0ある

2011-12-21 13:44:26,561 INFO sqlalchemy.engine.base.Engine.0x...1150 INSERT INTO tblfoo (`ModelID`, `ModelName`, `ModelMemo`) VALUES (%s, %s, %s) 
2011-12-21 13:44:26,561 INFO sqlalchemy.engine.base.Engine.0x...1150 (0, 'Bar', 'Foo') 
ID : 0 

です。

defaultを付けずに同じコードを実行すると、正しい出力が得られます。

フラグを立て答えはあなたのために働いた理由

from sqlalchemy import create_engine 
engine = create_engine('mysql://test:[email protected]/test1', echo=True) 

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() 

from sqlalchemy.orm import sessionmaker 
Session = sessionmaker(bind=engine) 

session = Session() 

from sqlalchemy import Column, Integer, Unicode 

class Foo(Base): 
    __tablename__ = 'tblfoo' 
    __table_args__ = {'mysql_engine':'InnoDB'} 

    ModelID = Column(Integer, primary_key=True, autoincrement=True) 
    ModelName = Column(Unicode(255), nullable=True, index=True) 
    ModelMemo = Column(Unicode(255), nullable=True) 

Base.metadata.create_all(engine) 

f = Foo(ModelName='Bar', ModelMemo='Foo') 
session.add(f) 
session.flush() 

print "ID :", f.ModelID 
+1

ニースキャッチは、デフォルト= 0に気付かなかった。 –

+1

サーバのログは常に問題を見つけるために働くでしょう:) – Nilesh

+1

Ugh ...はい、いいキャッチです。私の頭は、テーブルを作成するときにプライマリキーフィールドにデフォルト値が必要なSQL世界にありました。見つけてくれてありがとう。 – PlaidFan

1

session.flush()の代わりにsession.commit()を試してみてください。 f.ModelIDを使用できます。

+0

私はフラッシュの両方の後にそれを試してみましたが、コミットが、以下のエラーを受け取りました:はAttributeError:「フー」オブジェクトには、属性「ID」 – PlaidFan

+0

申し訳ありませんが、更新されていませんあなたのスキーマ宣言に使用されているようなModelIDを使用する答え。それでも、 'ModelID'ではなく' id'を使うべきでしょう。 –

+0

悲しいことに、私はそのアプローチをさまざまな方法で試してみたが、次のエラーが続く。ObjectDeletedError:インスタンス ''が削除されました。 – PlaidFan

1

わからないこのコードを試してみてください。しかし、私の場合は、実際に行をテーブルに挿入しません。私は最後にcommit()に電話する必要があります。

だから、コードの最後の数行は以下のとおりです。

f = Foo(ModelName='Bar', ModelMemo='Foo') 
session.add(f) 
session.flush() 

print "ID:", f.ModelID 

session.commit() 
関連する問題