2015-05-11 63 views
0

在現有的PostgreSQL表中,我想用UPDATE幾個現有的字段查找字段值(請參閱下面的代碼段)。有點像nice blog post中描述的那樣。但是,我不知道如何用Python字典來做到這一點。這裏談到的可怕的僞代碼:批量更新Python中的PostgreSQL字典

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 | chair | peace lily 
1 | table | english ivy 
... 

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

操作就應該是這樣的後

這是可能的還是我將不得不通過表循環?

+0

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

+0

你知道SQLAlchemy嗎? – Ashalynd

+0

@Ashalynd謝謝!我很確定鏈接的問題如何解決我的問題 - 對不起。我玩了SQLAlchemy的ORM。但顯然我不太清楚。它有一個工具嗎? – 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

顯然我在這裏沒有收到任何東西。你是說我應該事先準備一個字典列表,以便逐行更新表格?但我的數據庫非常龐大,隨機順序,替代字典有很多條目。如果可能,我想在原地進行更新。 – 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) 

注意:這個例子可能不太工作,因爲我與TEXT值替換INTEGER。這可能會引發錯誤ERROR: operator does not exist: integer = character varying。 在這種情況下,this answer可能會有所幫助。