On Dec 27, 2012, at 6:06 PM, Stefan Urbanek wrote:

> 
> On 27.12.2012, at 23:21, Michael Bayer <[email protected]> wrote:
> 
>> 
>> 
>> On Dec 27, 2012, at 4:55 PM, Stefan Urbanek wrote:
>> 
>>> 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'
>> 
>> It's the exception, rather than the rule, that the ordering of bound 
>> parameters in a "compiled" statement can be controlled - a simple INSERT 
>> statement yes, but for SELECT, UPDATE, DELETE the ultimate order of the 
>> params in the compiled string might not correspond to the order in which the 
>> bindparam() objects were created in the Python code.  So you can pass a list 
>> of lists in there but only if the statement you're executing is a raw 
>> string, using the paramstyle of the target DBAPI.   ClauseElement structures 
>> only support named parameters as input params and you can see the error 
>> where it's trying to detect "keys" is in _execute_clauseelement.  the path 
>> for a straight string is _execute_text.   
>> 
> 
> Thanks for clear explanation.
> 
> Is there a way how can I specify the order of params explicitly? I know the 
> order always, as I am holding metadata for whole data processing pipeline.

Well its a matter of the syntax of the SQL statement, thats why positional 
parameters are a little less than ideal to start with.    There's ways to 
reconcile these two systems but there's no natural API suggested by it.   In 
the case of an insert(), there is a natural order to the params which is the 
order of columns in the table.   You can do a quick dictionary translation like 
this:

        dict(zip((c.key for c in table.c), mytuple))

if the compiler were to accept positional parameters according to some ordering 
system it would need to be doing a step like this internally in any case.


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to