Hi,
I am trying to pass multiple rows as tuples into an INSERT statement.:
# buffer is list of lists/tuples, like: [ [1, "foo"], [2, "bar"], ... ]
insert = self.table.insert()
engine.execute(insert, buffer)
This fails with:
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.8.0b2-py2.7-macosx-10.8-x86_64.egg/sqlalchemy/engine/base.py", line 740, in _execute_clauseelement
keys = distilled_params[0].keys()
AttributeError: 'list' object has no attribute 'keys'
According to the documentation:
I can pass list of lists/tuples, not only a list of dictionaries.
For performance reasons (for ETL) I want to avoid creation of dictionaries if not necessary. What is the correct way to do insert of multiple values if I have rows as list of values?
Stefan
p.s.: I do not know much about SQLAlchemy internals, but the offending code:
distilled_params = _distill_params(multiparams, params)
if distilled_params:
keys = distilled_params[0].keys()
else:
keys = []
expects distilled_params to return a list of dictionaries, which is not 100% true according to python fallback implementation of the _distill_params method which might return a list/tuple: "Given arguments from the calling form *multiparams, **params, return a list of bind parameter structures, usually a list of dictionaries.". Code:
if isinstance(zero, (list, tuple)):
if not zero or hasattr(zero[0], '__iter__') and \
not hasattr(zero[0], 'strip'):
# execute(stmt, [{}, {}, {}, ...])
# execute(stmt, [(), (), (), ...])
return zero
Zero might be [(), (), (), ...].
The keys in offending code are used only for caching. Will this change of offending code work?
if distilled_params and hasattr(distilled_params[0], "keys"):