I am migrating from SA 0.4 to SA 0.5.2 and I am having some problems.
I am using the orm session object and issuing raw sql commands in some
cases for performance reasons.  Take the following example.  I have a
few hundred thousand tuples that will become new rows in 'mytable'.  I
want to issue a single fast sql statement to insert them.  In 0.4 I
had the following:

a_session.execute("insert into mytable values(%s, %s)", list
(list_of_2_ary_tuples))

I believe that this was being passed down to the postgres driver
directly, but this does not appear to work in 0.5.  It results in:

...(my code)
 File "/usr/lib/python2.5/site-packages/sqlalchemy/orm/session.py",
line 755, in execute
    clause, params or {})
  File "/usr/lib/python2.5/site-packages/sqlalchemy/engine/base.py",
line 824, in execute
    return Connection.executors[c](self, object, multiparams, params)
  File "/usr/lib/python2.5/site-packages/sqlalchemy/engine/base.py",
line 866, in _execute_clauseelement
    keys = params[0].keys()

That is fine.  That was a bit of a hack anyway.  So I started looking
for a new approach.  It looks as though 0.5 expects all bind params to
be dictionaries.  I thought I would map my list of tuples to a list of
dictionaries and pass that along.

So, I went with the following.

new_values = [('val1', 'val2'), ('val3', 'val4')]
a_session.execute(MyTableOrmObject.table.insert(), map( lambda val:
{'col0':val[0], 'col1':val[1]}, new_values ))

This works great, but remember, this is hundreds of thousands of items
in my actual use., so I didn't really want to duplicate my data
structure in memory, I thought I would switch out my map, for an imap,
ie:

new_values = [('val1', 'val2'), ('val3', 'val4')]
a_session.execute(MyTableOrmObject.table.insert(), imap( lambda val:
{'col0':val[0], 'col1':val[1]}, new_values ))

Unfortunately, the __distill_params method in engine base switches on
list and tuple types and gets this wrong.  There is some work to find
out if the object implements an iterator interface, but I'm not really
sure when that would be used.  Here is the stacktrace:

...(my code)
  File "/usr/lib/python2.5/site-packages/sqlalchemy/orm/session.py",
line 755, in execute
    clause, params or {})
  File "/usr/lib/python2.5/site-packages/sqlalchemy/engine/base.py",
line 824, in execute
    return Connection.executors[c](self, object, multiparams, params)
  File "/usr/lib/python2.5/site-packages/sqlalchemy/engine/base.py",
line 866, in _execute_clauseelement
    keys = params[0].keys()
AttributeError: 'tuple' object has no attribute 'keys'

Is this a bug?  Is there a way I can use the imap interface?  The
thing that complicates this, is that session.execute has a different
interface than connection or engines execute method so I can' really
control how things get passed from session to connection, and it's
asymetric.

Any ideas?

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

Reply via email to