2014-04-27 88 views
0

根據psycopg2: insert multiple rows with one query,使用psycopg2的execute而不是executemany會更加高效。其他人能證實嗎?使用psycopg2插入多行

以上的StackOverflow問題,建議使用mogrify創造的那種聲明:

INSERT INTO table VALUES (value1, value2), (value3, value4) 

是否有可能使用常規execute函數生成這樣的說法?我認爲這種形式的東西

cursor.execute("""INSERT INTO table VALUES (%s, %s), (%s, %s)""", ((value1,value2),(value3,value4))) 

會工作。

UPDATE:

舉例來說,我想我傳遞到執行SQL語句:

insert into history (timestamp) values (%s),(%s); 

與如下因素元組:

(('2014-04-27 14:07:30.000000',), ('2014-04-27 14:07:35.000000',)) 

但我回來是錯誤:

no results to fetch

+0

您沒有試試? –

+0

多值插入確實比'psycopg2'中的'executemany'更高效,但只有一點 - 如果每條語句插入數以萬計的行,內存使用就成爲一個問題。幾百或幾千(如果行較小)的批次可以很好。 –

回答

4

要使用execute方法將要插入的數據放入列表中。一個列表將被psycopg2修改爲一個數組。然後,你無視陣列並根據需要投入數值。

import psycopg2 

insert = """ 
    insert into history ("timestamp") 
    select value 
    from unnest(%s) s(value timestamp) 
    returning * 
;""" 

data = [('2014-04-27 14:07:30.000000',), ('2014-04-27 14:07:35.000000',)] 
conn = psycopg2.connect("host=localhost4 port=5432 dbname=cpn") 
cursor = conn.cursor() 
cursor.execute(insert, (data,)) 
print cursor.fetchall() 
conn.commit() 
conn.close() 

不確定與executemany的性能差異是否顯着。但我認爲以上是更好的。顧名思義,returning子句將返回插入的元組。

BTW timestamp是保留字,不應作爲列名使用。

+0

+1爲'unnest',並指出'時間戳'問題,這是使用ORM的一個補充。 – ChaimKut

+0

(在postgres中,它看起來像'timestamp'沒有保留。http://www.postgresql.org/docs/9.3/static/sql-keywords-appendix.html) – ChaimKut