2017-11-09 1 views
0

Ich versuche, mehrere Zeilen auf einmal zu aktualisieren, indem Sie ein Tupel-Tupel verwenden. Ich habe herausgefunden, wie die SQL-Anweisung von this post zu bauen, aber die Implementierung in psycopg2 hat sich als schwieriger erwiesen. Hier ist, was ich habe:psycopg2: Aktualisieren Sie mehrere Zeilen in einer Tabelle mit Werten aus einem Tupel-Tupel

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,)) 

Das Ergebnis ist ein Fehler: ProgrammingError: table "e" has 1 columns available but 2 columns specified Dies ist, weil die FROM Klausel interpretiert wird:

FROM (VALUES (("Richard",29),("Ronald",30))) 

statt:

FROM (VALUES ("Richard",29),("Ronald",30)) 

I kann dies umgehen, indem Sie Folgendes tun, aber es scheint unsicher:

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) 

Gibt es einen besseren Weg, dies zu tun?

Antwort

0

This post wies mich in die richtige Richtung. The documentation für extras.execute_values enthält auch ein gutes Beispiel mit der UPDATE Klausel.

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 
) 
Verwandte Themen