new stack trace when combining non-eq compare_values w/ SQL expression in ORM persist
Issue #3402
resolved
this is a 1.0 regression, though I'm pretty curious to see what 0.9 is doing that it isn't hitting this exception:
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
def comparator(a, b):
return a > b
class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
data = Column(PickleType(comparator=comparator))
e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
s = Session(e)
s.add(A(data='some data'))
s.commit()
a1 = s.query(A).first()
a1.data = func.foo("im a SQL expression")
s.commit()
#!
Traceback (most recent call last):
File "test.py", line 27, in <module>
s.commit()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 790, in commit
self.transaction.commit()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 392, in commit
self._prepare_impl()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 372, in _prepare_impl
self.session.flush()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 2004, in flush
self._flush(objects)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 2122, in _flush
transaction.rollback(_capture_exception=True)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/util/langhelpers.py", line 60, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 2086, in _flush
flush_context.execute()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/unitofwork.py", line 373, in execute
rec.execute(self)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/unitofwork.py", line 532, in execute
uow
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/persistence.py", line 170, in save_obj
mapper, table, update)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/persistence.py", line 613, in _emit_update_statements
lambda rec: (
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/persistence.py", line 456, in _collect_update_commands
value, state.committed_state[propkey]):
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/elements.py", line 2726, in __bool__
raise TypeError("Boolean value of this clause is not defined")
TypeError: Boolean value of this clause is not defined
Comments (3)
-
reporter -
reporter Here's the test case using something much more normal, occurs with boolean expressions, as the operator comes out as "is_()":
from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) data = Column(Boolean) e = create_engine("sqlite://", echo=True) Base.metadata.create_all(e) s = Session(e) s.add(A(data=None)) s.commit() a1 = s.query(A).first() a1.data = false() s.commit()
we might want to consider "is" and "isnot" OK for the
__bool__
here also but I'm happy not getting into that for now. -
reporter - changed status to resolved
- Fixed regression within the flush process when an attribute were
set to a SQL expression for an UPDATE, and the SQL expression when
compared to the previous value of the attribute would produce a SQL
comparison other than
==
or!=
, the exception "Boolean value of this clause is not defined" would raise. The fix ensures that the unit of work will not interpret the SQL expression in this way. fixes#3402
→ <<cset b0be9211c9a2>>
- Log in to comment
well if we have a SQL expression we know it has to be run, so in that case we skip the comparison. Confirm this is what 0.9 is doing and add a test to test_unitofworkv2: