読者です 読者をやめる 読者になる 読者になる

ConcurrentModificationError

SQLAlchemy

transactional=TrueにしたSessionを使っていると、

sqlalchemy.exceptions.ConcurrentModificationError: Updated rowcount 0 does not match number of objects updated 1

というエラーが出ることがあって、何のことか分からないまま、ずっと放置していたが、Google GroupのConcurrentModificationError with transactional sessionsというトピックに再現コードと解決策が出ていたので、大変参考になった。

以下は、上記のトピックを参考にした再現コード。

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

e = create_engine('sqlite://', echo=True)
Base = declarative_base(e)

class Person(Base):
    __tablename__ = 'person'
    id   = Column('id', Integer, primary_key=True)
    name = Column('name', String(40), nullable=False)

Base.metadata.create_all()
session = sessionmaker(autoflush=True, transactional=True, bind=e)()

p = Person(name="Eric")
session.save(p)

p = session.query(Person).filter_by(name="Eric").first()
p.name = "John"

session.rollback()
#session.clear()

p = session.query(Person).filter_by(name="Eric").all()

解決するには、session.rollback()に、session.clear()するようにする。