2015-05-13 2 views
2

У меня есть куча пар значений [(foo1, bar1), (foo2, bar2), ...], и я хочу сделать кучу обновлений «установить столбец« foo »в« foo1 », где столбец« bar »равен ' bar1».Массовая таблица UPDATE с предложением WHERE, которое является переменной

Я делаю это в Python с psycopg2. Я мог бы сделать executemany с запросом UPDATE table SET foo = %s WHERE bar = %s, но это много маленьких обновлений и с ума сойдет.

Как я могу сделать это легко и быстро? Возможно, что-то с временной таблицей?

Postgres версия 9.3.

ответ

1
UPDATE tbl t 
SET foo = v.foo 
FROM (
    VALUES ('foo1'::text, 'bar1'::text), ('foo2', 'bar2'), ... 
    ) v(foo, bar) 
WHERE t.bar = v.bar; 

Явные забросы типа необходимы только в первой строке выражения значений. text в примере - может быть что угодно. Строковый литерал в последующих строках принуждается к тем же типам.

В зависимости от формы у вас есть пары ключ-значение, другие методы могут быть более удобными. Например: создайте временную таблицу, COPY, затем используйте временную таблицу в UPDATE, как и любую другую таблицу. Реквизиты:

Или вы можете передать два простых массивов и unnest параллельно (синтаксис для Postgres 9.3):

UPDATE tbl t 
SET foo = v.foo 
FROM (
    SELECT unnest('{foo1,foo2,...}'::text[]) AS foo 
     , unnest('{bar1,bar2,...}'::text[]) AS bar 
    ) v(foo, bar) 
WHERE t.bar = v.bar; 

Postgres 9,4 имеет лучший способ:

Смежные вопросы