Почему два `Session`s, созданные на одном и том же` Engine ', видят незафиксированные изменения друг друга при использовании уровня изоляции `SERIALIZABLE`? - PullRequest
0 голосов
/ 03 мая 2020

Почему два Session, созданные на одном и том же Engine, видят незафиксированные изменения друг друга при использовании уровня изоляции SERIALIZABLE?

Как запрос print(s2.query(User).filter(User.name == 'bob').all()) может получить User "bob", когда этот пользователь был сброшен в базу данных по запросу print(s1.query(User).filter(User.name == 'alice').all()) (autoflush=True) и еще не зафиксирован?

Сначала я предположил, что проблема вызвана тем, что SQLite по умолчанию использует уровень изоляции READ_UNCOMITTED, пока я явно не установил уровень изоляции SERIALIZABLE и не получил тот же результат.

Кто-нибудь может объяснить?

from sqlalchemy import create_engine, Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session, relationship

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50), nullable=False)
    age = Column(Integer, nullable=False)
    team_id = Column(Integer, ForeignKey('teams.id'))

    team = relationship('Team', back_populates='users')

    def __repr__(self):
        return '<{}(id={},name={})>'.format(__class__.__name__, self.id, self.name)

class Team(Base):
    __tablename__ = 'teams'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50), nullable=False, unique=True)

    users = relationship('User', back_populates='team')

    def __repr__(self):
        return '<{}(id={},name={})>'.format(__class__.__name__, self.id, self.name)

engine = create_engine('sqlite:///:memory:', isolation_level='SERIALIZABLE', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine, autoflush=True, autocommit=False)

s1 = Session()
s2 = Session()

user1 = User(name='alice', age=20)
user2 = User(name='bob', age=30)

team1 = Team(name='pirates')
team1.users = [user1, user2]

s1.add(team1)

print(s1.query(User).filter(User.name == 'alice').all())
print(s2.query(User).filter(User.name == 'bob').all())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...