微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决将对象添加到会话时,SQLAlchemy是否保存顺序?

在仔细查看了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类型为object的对象,A然后又添加b类型为object的对象B,但是却a发现有外键b,则在INSERT forb之前,您将看到INSERT a

解决方法

这个断言是否总是通过?换句话说,在向会话添加新对象时,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用于测试。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。