2011-12-21 27 views
6

我刚才遇到了一个相当棘手的问题,经过测试,我发现没有可用的答案就足够了。使用SQLAlchemy从MySQL获取最后插入的值

我看过各种建议,但似乎没有人能够返回MySQL中auto_increment字段的最后一个插入值。

我见过使用session.flush()添加记录然后检索id的示例。但是似乎总是返回0

我也看到,提到使用session.refresh(例子),但会引发以下错误:InvalidRequestError:无法刷新例如'

我是什么试图做似乎非常简单,但我似乎无法弄清楚这个秘密。

我正在使用声明式的方法。

所以,我的代码看起来是这样的:

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() 

在这一点上,对象f,已被推到数据库,并已自动分配一个唯一的主键ID。但是,我似乎无法找到一种方法来获取在一些额外操作中使用的值。我想做到以下几点:

my_new_id = f.ModelID

我知道我可以简单地执行另一个查询基于其它参数来查找ModelID但我宁愿不要,如果在所有可能的。

我非常感谢对此问题的解决方案的任何见解。

感谢您的帮助提前。

回答

9

问题是你正在为自动增量设置defaul。因此,当它运行INSERT INTO查询服务器的日志

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 

所以输出0这是默认值和传递,因为你是为autoincrement列设置默认值。

如果我运行相同的代码而没有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。 – 2011-12-21 11:09:58

+1

服务器日志将始终工作,以找到问题:) – Nilesh 2011-12-21 11:34:26

+1

呃...是的,很好的接收。我的头在创建表时需要主键字段缺省值的SQL环境中。感谢您的发现。 – PlaidFan 2011-12-22 14:16:53

1

尝试使用session.commit()而不是session.flush()。然后您可以使用f.ModelID

+0

我尝试了两种冲洗后提交,但收到以下错误:AttributeError的:“富”对象有没有属性“ID” – PlaidFan 2011-12-21 05:26:10

+0

对不起,更新在您的模式声明中使用您使用ModelID的答案。不过,你应该使用'id'而不是'ModelID'。 – 2011-12-21 05:27:57

+0

不幸的是,我已经尝试了很多方法,并继续得到以下错误:ObjectDeletedError:Instance''已被删除。 – PlaidFan 2011-12-21 05:31:13

1

不知道为什么标记答案为你工作。但在我的情况下,这并不实际将该行插入表中。最后我需要拨打commit()

所以代码的最后几行:

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

print "ID:", f.ModelID 

session.commit() 
相关问题