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

Most upvoted comments

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.