sqlalchemy: Execute does not accept positional parameters that are not dicts
After #4848 execute('select ?', 1) will be coerced to execute(text('select ?'), 1), but the second case raises an error since it expects that all positional elements are dicts.
The actual sql texts is not important for this issue, since the error happens before the sql is actually executed.
Full example:
import sqlalchemy as sa
e = sa.create_engine('sqlite://')
e.execute('select ?', 42).scalar() # return 42
e.execute('select ?', (42, )).scalar() # return 42
e.execute(sa.text('select ?'), 42).scalar() # raises
e.execute(sa.text('select ?'), (42, )).scalar() # raises
In both cases the error is similar to this
----> 1 e.execute(sa.text('select ?'), 42)
..\lib\sqlalchemy\engine\base.py in execute(self, statement, *multiparams, **params)
2287 """
2288 connection = self.connect(close_with_result=True)
-> 2289 return connection.execute(statement, *multiparams, **params)
2290
2291 def exec_driver_sql(self, statement, *multiparams, **params):
..\lib\sqlalchemy\engine\base.py in execute(self, object_, *multiparams, **params)
990 raise exc.ObjectNotExecutableError(object_)
991 else:
--> 992 return meth(self, multiparams, params)
993
994 def _execute_function(self, func, multiparams, params):
..\lib\sqlalchemy\sql\elements.py in _execute_on_connection(self, connection, multiparams, params)
279 def _execute_on_connection(self, connection, multiparams, params):
280 if self.supports_execution:
--> 281 return connection._execute_clauseelement(self, multiparams, params)
282 else:
283 raise exc.ObjectNotExecutableError(self)
..\lib\sqlalchemy\engine\base.py in _execute_clauseelement(self, elem, multiparams, params)
1069 # ensure we don't retain a link to the view object for keys()
1070 # which links to the values, which we don't want to cache
-> 1071 keys = list(distilled_params[0].keys())
1072 else:
1073 keys = []
AttributeError: 'list' object has no attribute 'keys'
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 16 (15 by maintainers)
Commits related to this issue
- Deprecate plain string in execute and introduce `exec_driver_sql` Execution of literal sql string is deprecated in the :meth:`.Connection.execute` and a warning is raised when used stating that it wi... — committed to CaselIT/sqlalchemy by CaselIT 4 years ago
- Deprecate plain string in execute and introduce `exec_driver_sql` Execution of literal sql string is deprecated in the :meth:`.Connection.execute` and a warning is raised when used stating that it wi... — committed to sqlalchemy/sqlalchemy by CaselIT 4 years ago
I’d not go too far with this right now. im still building out the concept of the “future” package so this will look more natural as it gets there. the deprecation warning for text() and adding exec_driver_sql is fine though.