[Sqlalchemy-tickets] Issue #3229: query.update shouldn' use the hybrid_property expression method (
Brought to you by:
zzzeek
|
From: Jean-Sébastien S. <iss...@bi...> - 2014-10-17 11:04:36
|
New issue 3229: query.update shouldn' use the hybrid_property expression method https://bitbucket.org/zzzeek/sqlalchemy/issue/3229/queryupdate-shouldn-use-the Jean-Sébastien Suzanne: Hi Mike, I have a second request with the [report #3228](https://bitbucket.org/zzzeek/sqlalchemy/issue/3228/queryupdate-does-not-resolve-string-names) this is the example: from sqlalchemy import Column, Integer, String, create_engine, func from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.hybrid import hybrid_property engine = create_engine('sqlite:///memory') Base = declarative_base() class Person(Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) first_name = Column(String(64)) last_name = Column(String(64)) @hybrid_property def name(self): return self.first_name + ' ' + self.last_name @name.setter def name(self, value): self.first_name, self.last_name = value.split(' ', 1) @name.expression def name(cls): return func.concat(cls.first_name, ' ', cls.last_name) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() t = Person(name='James BOND') session.add(t) session.query(Person).update({Person.name: 'Dr. No'}) And the traceback: Traceback (most recent call last): File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1022, in _execute_context context) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/engine/default.py", line 436, in do_execute cursor.execute(statement, parameters) sqlite3.OperationalError: near "(": syntax error The above exception was the direct cause of the following exception: Traceback (most recent call last): File "./bin/python", line 63, in <module> exec(compile(__file__f.read(), __file__, "exec")) File "hybrid_property.py", line 37, in <module> session.query(Person).update({Person.name: 'Dr. No'}) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/orm/query.py", line 2848, in update update_op.exec_() File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/orm/persistence.py", line 906, in exec_ self._do_exec() File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/orm/persistence.py", line 1036, in _do_exec update_stmt, params=self.query._params) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/orm/session.py", line 982, in execute bind, close_with_result=True).execute(clause, params or {}) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/engine/base.py", line 800, in execute return meth(self, multiparams, params) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/sql/elements.py", line 323, in _execute_on_connection return connection._execute_clauseelement(self, multiparams, params) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/engine/base.py", line 897, in _execute_clauseelement compiled_sql, distilled_params File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1029, in _execute_context context) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1230, in _handle_dbapi_exception exc_info File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/util/compat.py", line 188, in raise_from_cause reraise(type(exception), exception, tb=exc_tb, cause=exc_value) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/util/compat.py", line 181, in reraise raise value.with_traceback(tb) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1022, in _execute_context context) File "/Users/jssuzanne/erpblok/anyblok/sqlalchemy/lib/sqlalchemy/engine/default.py", line 436, in do_execute cursor.execute(statement, parameters) sqlalchemy.exc.OperationalError: (OperationalError) near "(": syntax error 'UPDATE person SET concat(first_name, ?, last_name)=?' ('Dr. No', ' ') I think the better way is adding new callback in hybrid_property like @name.update_expression def name(cls, value): first_name, last_name = value.split(' ', 1) return cls.first_name = first_name, cls.last_name = last_name Regard, |