Pregunta

I'm programming in Jython to an SQL database, using the com.ziclix.python.sql package. I'm wondering if the package has support in its prepared statements for SQL INSERT/UPDATE statements where you pass multiple rows of values rather than just one row, so that you're inserting multiple rows in one INSERT statement. Let me explain.

Here's a basic SQL INSERT statement:

INSERT INTO Names (FirstName, LastName) VALUES ("John", "Doe");

Using the zxJDBC prepared statement, this is pretty trivial:

# Assume cursor object
statement = 'INSERT INTO Names (FirstName, LastName) VALUES (?, ?)'
cursor.execute(statement, ('John', 'Doe'))

But the kind of INSERT statement I'm interested in is where you insert multiple rows of values, like so:

INSERT INTO Names (FirstName, LastName) VALUES ("John", "Doe"), ("Mary", "Smith");

Is there some way to do this using prepared statements? I would rather use prepared statements to build up an SQL query rather than string interpolation, if possible. Thanks.

¿Fue útil?

Solución

Since zxJDBC implements PEP 249 " Python Database API Specification v2.0", you can use the method executemany() to accomplish this:

# Assume cursor object
statement = 'INSERT INTO Names (FirstName, LastName) VALUES (?, ?)'
cursor.executemany(statement, (
    ('John', 'Doe'),
    ('Mary', 'Smith'),
    # ...
    )
)

Update: Looks like this is too slow, since zxJDBC just calls execute many times without optimising the query. Instead you could do:

from itertools import chain
statement = 'INSERT INTO Names (FirstName, LastName) VALUES {values}'.format(
    values = ','.join('(?, ?)' for _ in input_seq))
input_seq = (
    ('John', 'Doe'),
    ('Mary', 'Smith'),
    # ...
    )
cursor.execute(statement, list(chain(*input_seq)))

This does involve some string manipulation, but it preserves the use of parameter lists and allows a single DB round-trip.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top