2015-05-11 2 views
0

В существующей таблице PostgreSQL я хотел бы указать UPDATE несколько существующих столбцов со значениями из словарного поиска (см. Ниже). Как это описано в этом nice blog post. Однако я не могу понять, как это сделать с помощью словаря Python. Здесь приходит страшная псевдокод:Массовое обновление PostgreSQL из Python dict

d = {10:'chair', 11:'table', 12:'lamp', 
    20:'english ivy', 21:'peace lily', 22:'spider plant'} 

curs.execute(""" 
    UPDATE my_table t 
    SET furniture = %(t.furniture)s, 
    SET plant = %(t.plant)s""", 
    d) 

оригинальный таблица будет выглядеть примерно так:

gid | furniture | plant 
----------------------- 
0 | 10  | 21 
1 | 11  | 20 
... 

После операция должна выглядеть следующим образом:

gid | furniture | plant 
----------------------------- 
0 | chair | peace lily 
1 | table | english ivy 
... 

Возможно ли это, или мне придется пройти через стол?

+0

http://stackoverflow.com/questions/7019831/bulk-batch-update-upsert-in-postgresql – Ashalynd

+0

Вы знаете о SQLAlchemy? – Ashalynd

+0

@Ashalynd Спасибо! Я уверен, что связанный вопрос может решить мою проблему - извините. Я играл с ORM SQLAlchemy. Но, видимо, я не знаю этого достаточно хорошо. У этого есть инструмент для этого? – n1000

ответ

1

попробовать это:

rows = (
    {'gid': 10, 'furniture': 10, 'plant': 10}, 
    {'gid': 20, 'furniture': 20, 'plant': 20} 
) 
cur.executemany(
    ''' 
     UPDATE myTable 
     SET 
      furniture = %(furniture)s, 
      plant = %(plant)s 
     WHERE 
      gid = %(gid)s 
    ''', 
    rows 
) 
+0

Спасибо, но мне кажется, что в моем вопросе не было ясно. Сейчас я отредактирую его ... Мне очень жаль. – n1000

+0

Если тип myTable.furniture совместим с текстом (текст, символ меняется и т. Д.) - никаких проблем. Просто измените значение строк (rows [i] .furniture = 'chair'). В противном случае сначала измените тип столбца (ALTER TABLE myTable ALTER COLUMN furniture TYPE text;) – cetver

+0

Очевидно, что я ничего не получаю. Вы говорите, что я должен подготовить список словарей заранее, чтобы обновить таблицу в основном по строкам? Но моя база данных огромна, в случайном порядке, а у замены dict есть много записей. Я хотел бы обновить на месте - если это возможно. – n1000

0

Подход catver работ. Однако я обнаружил, что создание временной таблицы оказалось более эффективным.

import psycopg2 
from psycopg2.extensions import AsIs 

rows = zip(d.keys(), d.values()) 
curs.execute(""" 
    CREATE TEMP TABLE codelist(DKEY INTEGER, DVALUE TEXT) 
    ON COMMIT DROP""") 

curs.executemany(""" 
    INSERT INTO codelist (DKEY, DVALUE) 
    VALUES(%s, %s)""", 
    rows) 

for i in [(AsIs('furniture'), AsIs('furniture')), (AsIs('plant'), AsIs('plant'))]: 
    curs.execute(""" 
     UPDATE my_table 
     SET %s = codelist.DVALUE 
     FROM codelist 
     WHERE codelist.DKEY = my_table.%s; 
     """, i) 

NB: Этот пример не совсем работа, потому что я замена INTEGER с TEXT значениями. Это может вызвать ошибку ERROR: operator does not exist: integer = character varying. В этом случае может помочь this answer.

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