Почему два 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())