【问题标题】:SQLAlchemy "excluded" PostgreSQL namespace in INSERT ... ON CONFLICTSQLAlchemy 在 INSERT 中“排除”了 PostgreSQL 命名空间...... ON CONFLICT
【发布时间】:2017-07-02 05:25:12
【问题描述】:

我找不到通过 SQLAlchemy 执行 PostgreSQL INSERT .. ON UPDATE 的方法。 有没有办法处理多行,一次对整个数据执行操作?

我尝试使用 pandas 数据帧中的值进行更新插入:

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)

这是在一行的基础上工作的,因为每一行都是单独处理的——它工作得非常慢(7000 行需要 20 分钟)。 有没有办法将此操作作为单个 SQL 语句执行?

我正在寻找某种机会将{'column_name':'excluded .column_name'} 之类的参数传递给语句的更新部分,其中“排除”不会被解析为字符串值的一部分,而是作为 SQL 文字.有没有办法做到这一点?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    使用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

    【讨论】:

      猜你喜欢
      • 2016-01-23
      • 2016-07-21
      • 1970-01-01
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      • 2018-12-17
      • 2017-05-28
      • 1970-01-01
      相关资源
      最近更新 更多