I used to use execute_values
in psycopg2 but it’s gone in psycopg3. I tried following the advice in this answer or this github post, but it just doesn’t seem to work for my use case. I’m trying to insert multiple values, my SQL is like so:
sql = INSERT INTO activities (type_, key_, a, b, c, d, e)
VALUES %s
ON CONFLICT (key_) DO UPDATE
SET
a = EXCLUDED.a,
b = EXCLUDED.b,
c = EXCLUDED.c,
d = EXCLUDED.d,
e = EXCLUDED.e
values = [['type', 'key', None, None, None, None, None]]
But doing cursor.executemany(sql, values)
results in {ProgrammingError}the query has 1 placeholder but 7 parameters were passed
. I tried many variations with extra parentheses etc. but always it results in some error. For example doing self.cursor.executemany(sql, [values])
results in syntax error near or at "$1": Line 3: VALUES $1
.
2
Answers
The values clause should be consist of one
%s
placeholder for each column being inserted, separated by commas and all within parentheses, like this:We can produce the desired string with string manipulation:
However psycopg provides tools for composing SQL statements, and it may be safer to use these tools rather than relying on string manipulation if your query building is very dynamic. Using these tools, you would have this (I’ve added the parentheses into the main query string this time, as there is no benefit in not doing so):
I would suggest to serialize and pass the arguments as JSON.
SQL and
values
would channge like this:Please note that some type casts may be needed since
->>
operator yieldstext
. The same approach can be used successfully in different scenarios. It remains possible to use prepared statements thus checking risk of SQL injection.