psycopg2: обновить несколько строк в таблице значениями из кортежа кортежей

Я пытаюсь обновить несколько строк одновременно, используя кортеж кортежей. Я понял, как создать оператор 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'\1)', sql)

sql = c.execute(sql)

Есть лучший способ сделать это?


person tdnelson2    schedule 09.11.2017    source источник


Ответы (1)


Этот пост указал мне на правильное направление. Документация для 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
)
person tdnelson2    schedule 09.11.2017
comment
ой, это кажется таким окольным. Кому-нибудь еще кажется, что каждый раз, когда что-то терпит неудачу в psycopg2, это гарантированно займет час гугления, чтобы найти точный синтаксис, чтобы заставить его работать? Например, почему огромная разница в синтаксисе между массовой вставкой и массовым обновлением. Цените ответ, просто выдыхая - person Adam Hughes; 08.05.2020