unincremented version id counter on superclass
Issue #3996
resolved
from #3673
from sqlalchemy import *
from sqlalchemy import types
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy import event
from datetime import datetime
Base = declarative_base()
class Foo(Base):
__tablename__ = 'foo'
id = Column(types.Integer, primary_key=True)
type = Column(types.Unicode(64), nullable=False)
bar = Column(types.DateTime(), nullable=False)
other = Column(types.Integer)
__mapper_args__ = {
'polymorphic_on': u'type',
'polymorphic_identity': u'Foo',
'version_id_col': bar,
'version_id_generator': False
}
class FooDerived(Foo):
__tablename__ = 'foo_derived'
id = Column(types.Integer, ForeignKey(u'foo.id'), primary_key=True)
other2 = Column(types.Integer)
__mapper_args__ = {
'polymorphic_identity': u'FooDerived'
}
e = create_engine('sqlite:///:memory:', echo='debug')
Base.metadata.drop_all(e)
Base.metadata.create_all(e)
session = Session(e, autocommit=True, autoflush=False, expire_on_commit=False)
x = FooDerived()
x.bar = datetime(1970, 1, 1)
session.add(x)
session.flush()
x.other2 = 1
session.flush()
it tries to update the primary table:
#!
OperationalError: (sqlite3.OperationalError) near "WHERE": syntax error [SQL: u'UPDATE foo SET WHERE foo.id = ? AND foo.bar = ?'] [parameters: (1, '1970-01-01 00:00:00.000000')]
docs:
#!
We can update our ``User`` object without incrementing the version counter
as well; the value of the counter will remain unchanged, and the UPDATE
statement will still check against the previous value. This may be useful
for schemes where only certain classes of UPDATE are sensitive to concurrency
issues::
Comments (2)
-
reporter -
reporter - changed status to resolved
Detect no params w/ manual version_id counter and set to itself
Fixed bug where programmatic version_id counter in conjunction with joined table inheritance would fail if the version_id counter were not actually incremented and no other values on the base table were modified, as the UPDATE would have an empty SET clause. Since programmatic version_id where version counter is not incremented is a documented use case, this specific condition is now detected and the UPDATE now sets the version_id value to itself, so that concurrency checks still take place.
Change-Id: I80e385bffeed4851cc20131cbe983c173a46f655 Fixes:
#3996→ <<cset 0a67c1305266>>
- Log in to comment
https://gerrit.sqlalchemy.org/409