2017-07-01 56 views
1

我找不到通過SQLAlchemy執行PostgreSQL INSERT .. ON UPDATE的方法。 有沒有辦法做到與多行,一次執行整個數據的操作?SQLAlchemy「排除」INSERT中的PostgreSQL命名空間... ON CONFLICT

我試着從一個數據幀的大熊貓與值UPSERT:

for insert_values in df.to_dict(orient='records'): 
    insert_statement = sqlalchemy.dialects.postgresql.insert(orders_to_channels).values(insert_values) 
    upsert_statement = insert_statement.on_conflict_do_update(
     constraint='orders_to_channels_pkey', 
    set_=insert_values 
    conn.execute(upsert) 

這個工程按行和每一行另案處理 - 它的工作原理非常緩慢(20分鐘,7000行)。 有沒有辦法將這個操作作爲單個SQL語句執行?

我正在尋找某種機會,將諸如{'column_name':'excluded .column_name'}之類的參數傳遞給語句的更新部分,其中「excluded」不會被解析爲字符串值的一部分,而是被解析爲SQL文字。有沒有辦法做到這一點?

回答

0

使用專用別名postgresql.dml.Insert對象的excluded

insert_statement = sqlalchemy.dialects.postgresql.insert(orders_to_channels) 
upsert_statement = insert_statement.on_conflict_do_update(
    constraint='orders_to_channels_pkey', 
    set_={ 'column_name': insert_statement.excluded.column_name } 
) 
insert_values = df.to_dict(orient='records') 
conn.execute(upsert_statement, insert_values) 

注意psycopg2's executemany() is essentially equivalent to execute() in a loop,所以你可能看不到一樣大的性能提升預期。你可以嘗試使用"multiple values" syntax

insert_values = df.to_dict(orient='records') 
insert_statement = sqlalchemy.dialects.postgresql.insert(orders_to_channels).values(insert_values) 
... 

但是,that might not be any faster