[DB-SIG] Towards a single parameter style

Matthew T. Kromer matt@zope.com
Wed, 19 Feb 2003 09:56:41 -0500


Kevin Jacobs wrote:

>Again, no.  The goal is to have multiple commands floating around.  In the
>interest of clarity, here is a more realistic use case:
>
>  connection = connect(...)
>  commands = getSQL()
>  commands = [ connection.prepare(sql) for sql in commands ]
>  descrs   = [ command.description for command in commands ]
>
>  cursor = connection.cursor()
>  while 1:
>    op = getNextOperation()
>    i,args = decodeOp(op, descrs)
>    cursor.execute(commands[i], args)
>
>This is a little contrived, since our real code doesn't dispatch commands in
>a single loop.  They're spread out in a hierarchy of object and triggered by
>data-driven events.  In some tests using native (vs. DB-API) interfaces, we
>obtain a 2.4x speedup by using prepared queries against a local database.
>  
>

For what its worth, I ended up supporting something *similar* to this 
for DCOracle2 in order to support some old features of DCOracle.  

Connection.prepare(statement) returns a new cursor with a prepared 
statement.  It acts just like a cursor, except that if only keyword 
arguments are passed, it will use its previously prepared statement for 
execution, otherwise None may be passed in as the statement to use the 
previously prepared statement.  This isn't perfect -- the prepared 
cursor is still a cursor, and so it won't restrict itself to only using 
the command that it was originally prepared with, and the original 
DCOracle case never  used positional parameters, it only handles keyword 
arguments:

    cmd = connection.prepare(statement)
    cmd.execute(var1=val1, var2=val2, [...])

However, your example clearly demonstrates a "statement handle" type of 
object which is distinct from a cursor (even though in most DB's they 
are probably the same -- certainly they are for Oracle.)