Something a bit more normal now.

Combining optimistic concurrency control with cascading PK updates is
problematic, if you load the child relation, the session issues
unecessary updates for the children, resulting in
ConcurrentModificationError

"""

import sqlalchemy as sql
from sqlalchemy import orm
from sqlalchemy.ext.declarative import declarative_base

__metaclass__ = type

engine = sql.create_engine("postgresql:///avdd")
metadata = sql.MetaData(bind=engine)
db = orm.create_session(bind=engine, autocommit=False)
T = declarative_base(metadata=metadata)

class P(T):
    __tablename__ = 'p'
    id = sql.Column(sql.String, primary_key=True)
    version = sql.Column(sql.Integer, nullable=False, default=1)
    cc = orm.relation('C', backref='parent', passive_updates=True)
    __mapper_args__ = {'version_id_col': version}

class C(T):
    __tablename__ = 'c'
    i = sql.Column(sql.String, primary_key=True)
    p = sql.Column(sql.String,
                   sql.ForeignKey('p.id', onupdate='cascade',
ondelete='cascade'),
                   primary_key=True)
    version = sql.Column(sql.Integer, nullable=False, default=1)
    __mapper_args__ = {'version_id_col': version}

metadata.create_all()
P.__table__.delete().execute()

with db.transaction:
    p = P(id='P1', cc=[C(i='C.1'), C(i='C.2')])
    db.add(p)

db.expunge_all()
p = db.query(P).first()

with db.transaction:
    p.id = 'P2'
    # ok, no ConcModError

db.expunge_all()
p = db.query(P).first()

with db.transaction:
    p.id = 'P3'
    p.cc
    # issues spurious updates, throws ConcModError

"""

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to