Сохраняет ли 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 ответа

Решение

Посмотрев немного на источник SQLAlchemy, он выглядит add() записи, когда он был вставлен: https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/orm/session.py

Соответствующий фрагмент:

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

К сожалению, это только подтверждение уровня реализации. Я не смог найти в документации ничего, что гарантировало бы это...

Обновление: с тех пор я немного больше в этом разбираюсь, оказалось, что в SQLAlchemy есть концепция Unit of Work, которая несколько определяет порядок во время сброса: http://www.aosabook.org/en/sqlalchemy.html (поиск единицы работы).

Внутри того же класса порядок действительно определяется порядком, add назывался. Тем не менее, вы можете увидеть разные порядки в INSERT между разными классами. Если вы добавите объект a типа A а позже добавить объект b типа B, но a оказывается, есть внешний ключ к bвы увидите ВСТАВКУ для b перед вставкой для a,

Нет, это делает их, когда вы делаете коммит, а не когда вы добавляете.

Другие вопросы по тегам