6

我刚刚遇到了一个相当棘手的问题,经过测试,我发现没有一个可用的答案是足够的。

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

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

我还看到提到使用 session.refresh() 但引发以下错误的示例: InvalidRequestError: Could not refresh instance ''

我正在尝试做的事情似乎非常简单,但我似乎无法弄清楚其中的秘密。

我正在使用声明性方法。

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

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 已经被推送到 DB,并被自动分配了唯一的主键 id。但是,我似乎无法找到一种方法来获取在某些附加操作中使用的值。我想做以下事情:

my_new_id = f.ModelID

我知道我可以简单地执行另一个查询来根据其他参数查找 ModelID,但如果可能的话,我不希望这样做。

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

我在这里先向您的帮助表示感谢。

4

3 回答 3

9

问题是您正在设置defaul自动增量。因此,当它运行插入查询时,服务器的日志是

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:test@localhost/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
于 2011-12-21T08:22:21.370 回答
2

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

于 2011-12-21T05:20:39.633 回答
1

不确定为什么标记的答案对您有用。但就我而言,这实际上并没有将行插入表中。最后我需要打电话commit()

所以最后几行代码是:

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

print "ID:", f.ModelID

session.commit()
于 2016-12-12T21:44:56.837 回答