I'm attempting to update several rows at once using a tuple of tuples.
I figured out how to construct the sql statement from this post, but implementing it in psycopg2
has proven to be more challenging.
Here's what I have:
c = db.cursor()
new_values = (("Richard",29),("Ronald",30))
sql = """UPDATE my_table AS t
SET name = e.name
FROM (VALUES %s) AS e(name, id)
WHERE e.id = t.id;"""
c.execute(sql, (new_values,))
The result is an error: ProgrammingError: table "e" has 1 columns available but 2 columns specified
This is because the FROM
clause is being interpreted as:
FROM (VALUES (("Richard",29),("Ronald",30)))
instead of:
FROM (VALUES ("Richard",29),("Ronald",30))
I can work around this by doing the following but it seems unsafe:
import re
c = db.cursor()
sql = """UPDATE my_table AS t
SET name = e.name
FROM (VALUES %s) AS e(name, id)
WHERE e.id = t.id;"""
sql = c.mogrify(sql, (new_values,))
# Replace the first occurance of '((' with '('.
sql = sql.replace('((', '(',1)
# Replace the last occurance of '))' with ')'.
sql = re.sub(r'(.*)\)\)', r'\1)', sql)
sql = c.execute(sql)
Is there a better way to do this?
psycopg2
it's guaranteed to take over an hour of googling to find the exact syntax to make it work? Like why the huge difference in syntax between a bulk insert and bulk update Appreciate the answer, just venting – Adrastus