psycopg2:使用元组的元组中的值更新 table 中的多行
psycopg2: Update multiple rows in a table with values from a tuple of tuples
我正在尝试使用元组的元组一次更新多行。
我想出了如何从 this post 构造 sql 语句,但在 psycopg2
中实现它已被证明更具挑战性。
这是我拥有的:
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,))
结果出错:ProgrammingError: table "e" has 1 columns available but 2 columns specified
这是因为 FROM
子句被解释为:
FROM (VALUES (("Richard",29),("Ronald",30)))
而不是:
FROM (VALUES ("Richard",29),("Ronald",30))
我可以通过执行以下操作来解决此问题,但它似乎不安全:
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')', sql)
sql = c.execute(sql)
有更好的方法吗?
This post pointed me in the right direction. The documentation for extras.execute_values
也包含一个使用 UPDATE
子句的好例子。
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
)
我正在尝试使用元组的元组一次更新多行。
我想出了如何从 this post 构造 sql 语句,但在 psycopg2
中实现它已被证明更具挑战性。
这是我拥有的:
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,))
结果出错:ProgrammingError: table "e" has 1 columns available but 2 columns specified
这是因为 FROM
子句被解释为:
FROM (VALUES (("Richard",29),("Ronald",30)))
而不是:
FROM (VALUES ("Richard",29),("Ronald",30))
我可以通过执行以下操作来解决此问题,但它似乎不安全:
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')', sql)
sql = c.execute(sql)
有更好的方法吗?
This post pointed me in the right direction. The documentation for extras.execute_values
也包含一个使用 UPDATE
子句的好例子。
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
)