问题
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?
回答1:
This post pointed me in the right direction. The documentation for extras.execute_values
also contains a great example using the UPDATE
clause.
c = db.cursor()
update_query = """UPDATE my_table AS t
SET name = e.name
FROM (VALUES %s) AS e(name, id)
WHERE e.id = t.id;"""
psycopg2.extras.execute_values (
c, update_query, new_values, template=None, page_size=100
)
来源:https://stackoverflow.com/questions/47192163/psycopg2-update-multiple-rows-in-a-table-with-values-from-a-tuple-of-tuples