简体   繁体   English

SQLAlchemy在INSERT中“排除”PostgreSQL命名空间... ON CONFLICT

[英]SQLAlchemy “excluded” PostgreSQL namespace in INSERT … ON CONFLICT

I can't find a way to execute PostgreSQL INSERT .. ON UPDATE through SQLAlchemy. 我找不到通过SQLAlchemy执行PostgreSQL INSERT ... ON UPDATE的方法。 Is there a way to do it with multiple rows, performing the operation on the whole data at once? 有没有办法用多行来做,一次对整个数据执行操作?

I try to upsert with values from a pandas dataframe: 我尝试使用pandas数据帧中的值进行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)

This works on a row basis and as every row is handled separately - it works terribly slow (20 minutes for 7000 rows). 这在行的基础上工作,并且每行都是单独处理的 - 它的工作速度非常慢(7000行为20分钟)。 Is there a way to perform this operation as a single SQL statement? 有没有办法将此操作作为单个SQL语句执行?

I am looking for some kind of an opportunity to pass parameters like {'column_name':'excluded .column_name'} to the update part of the statement, where "excluded" won't be parsed as a part of the string value, but rather as a SQL literal. 我正在寻找某种机会将{'column_name':'excluded .column_name'}等参数传递给语句的更新部分,其中“excluded”不会被解析为字符串值的一部分,但是而是作为SQL文字。 Is there a way to do this? 有没有办法做到这一点?

Use the special alias excluded of the postgresql.dml.Insert object: 使用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)

Note that psycopg2's executemany() is essentially equivalent to execute() in a loop , so you might not see as big a performance upgrade as expected. 请注意, psycopg2的executemany()基本上等同于循环中的execute() ,因此您可能看不到预期的性能升级。 You could try using the "multiple values" syntax : 您可以尝试使用“多值”语法

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

But, that might not be any faster . 但是, 这可能不会更快

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM