在向会话添加对象时,SQLAlchemy是否保存顺序?

时间:2012-04-14 14:28:06

标签: python database orm sqlalchemy

这个断言总是通过吗?换句话说,在向会话中添加新对象时,SQLAlchemy是否保存顺序(在生成INSERT查询时)?

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.engine import create_engine
from sqlalchemy.types import Integer
from sqlalchemy.schema import Column

engine = create_engine('sqlite://')
Base = declarative_base(engine)
Session = sessionmaker(bind=engine)
session = Session()

class Entity(Base):
    __tablename__ = 'entity'
    id = Column(Integer(), primary_key=True)
Entity.__table__.create(checkfirst=True)


first = Entity()
session.add(first)

second = Entity()
session.add(second)

session.commit()
assert second.id > first.id
print(first.id, second.id)

没有,在制作中我使用postgresql,sqlite用于测试。

2 个答案:

答案 0 :(得分:11)

在查看SQLAlchemy源代码之后,它在插入时看起来像add()个记录:https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/orm/session.py#L1719

相关摘录:

def _save_impl(self, state):
    if state.key is not None:
        raise sa_exc.InvalidRequestError(
            "Object '%s' already has an identity - it can't be registered "
            "as pending" % state_str(state))

    self._before_attach(state)
    if state not in self._new:
        self._new[state] = state.obj()
        state.insert_order = len(self._new) # THE INSERT ORDER IS SAVED!
    self._attach(state)

这是从Session.add =>调用的。 self._save_or_update_state => self._save_or_update_impl => self._save_impl

然后在_sort_states保存时使用它:https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/orm/persistence.py#L859

不幸的是,这只是实施级别的证明。我在文档中找不到任何保证它的东西......

<强>更新: 我已经对此进行了更多研究,结果发现在SQLAlchemy中有一个名为工作单元的概念,它在某种程度上定义了刷新期间的顺序:http://www.aosabook.org/en/sqlalchemy.html(搜索工作单元)。

在同一个班级中,顺序确实取决于add被调用的顺序。但是,您可能会在不同类之间的INSERT中看到不同的顺序。如果您添加a类型的对象A,然后添加类型为b的对象B,但a的外键为{{1}在b的INSERT之前,您会看到b的INSERT。

答案 1 :(得分:-2)

不,它会在您提交时执行,而不是在您添加时执行。