detect row-switches for version_id_col
First, version_id_col doesn't respect row switches. Solution is to fetch the old version from the row_switch state.
Second issue is similiar, but more like an "offline row-switch" where version=1. Consider two concurrent transactions:
# tx1
x = db.query(X).get(1) # version = 1
db.delete(x)
db.commit()
# ...
db.add(X(data='"offline" row-switch'))
db.commit() # version = 1
# tx2 concurrent with above
x = db2.query(X).get(1) # version = 1
x.attr = 'I overwrote row-switch!'
db.commit() # version = 2
You may think that it's just an edge case for version=1, but that's probably the most common version number!
The solution in this case is to use version identifiers that aren't local to the object, e.g. UUIDs.
I have a patch that allows supplying a version_id_generator function, defaulting to an integer increment.
Comments (5)
-
repo owner -
Account Deleted Can you at least get the first part in for the 0.6 release? The patch is trivial and fixes a bug (adding int to None):
Traceback (most recent call last): File "test_occ_rowswitch.py", line 41, in <module> db.commit() File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/session.py", line 655, in commit self.transaction.commit() File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/session.py", line 368, in commit self._prepare_impl() File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/session.py", line 352, in _prepare_impl self.session.flush() File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/session.py", line 1325, in flush self._flush(objects) File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/session.py", line 1403, in _flush flush_context.execute() File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/unitofwork.py", line 261, in execute UOWExecutor().execute(self, tasks) File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/unitofwork.py", line 753, in execute self.execute_save_steps(trans, task) File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/unitofwork.py", line 768, in execute_save_steps self.save_objects(trans, task) File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/unitofwork.py", line 759, in save_objects task.mapper._save_obj(task.polymorphic_tosave_objects, trans) File "/home/avdd/tmp/src/sqlalchemy.6/lib/sqlalchemy/orm/mapper.py", line 1377, in _save_obj params[col.key](col.key) = params[col._label](col._label) + 1 TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
-
repo owner - changed milestone to 0.6.0
sure...
-
repo owner - changed status to resolved
looks great, the whole thing is in 84c6857d214725246c28f97b4dba9d52385f9a37.
-
repo owner - removed milestone
Removing milestone: 0.6.0 (automated comment)
- Log in to comment
Hibernate offers numerical and timestamp versioning: http://docs.jboss.org/hibernate/stable/core/reference/en/html/mapping.html#mapping-declaration-version . the timestamp is probably easier to deal with than the uuid since it is also meaningful, and should probably auto-detect for
Integer
andDateTime
types. (uuid is also fine too though there's no generic type to detect that on).