Подтвердить что ты не робот

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

4b9b3361

Ответ 1

Немного взглянув на источник 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 окажется, что у него есть внешний ключ, b вы увидите INSERT для b до INSERT для a.

Ответ 2

Нет, он делает это, когда вы совершаете, а не когда добавляете.