从另一个表的SQLAlchemy快速批量更新

时间:2019-09-13 19:11:22

标签: postgresql sqlalchemy

我想将table_a中尚不存在的记录从table_b插入table_a中。我已经有Postgres SQL代码来执行此操作,但是现在我的团队要求我改用ORM(SQLAlchemy)。

INSERT INTO table_a
SELECT
  composite_pk1,
  composite_pk2,
  col_c,
  col_d
FROM table_b
ON CONFLICT (
  composite_pk1,
  composite_pk2
) DO NOTHING

我有近一百万行和大约15列(示例中未显示)。我需要此查询要快速,这就是为什么我认为发布在here上的解决方案不适用于我的用例的原因。

出于性能方面的考虑,我还希望避免将Python函数视为数据管道。我不想通过网络将table_b的许多行转移到我的函数中,只是想通过网络再次将它们推回到table_a。也就是说,我希望插入完全在Postgres上进行,而我已经使用原始SQL查询完成了插入。

1 个答案:

答案 0 :(得分:1)

使用bulk_update_mappings函数可能是通过使用SQLAlchemy ORM进行更新的最快方法,该函数仅允许您根据字典列表进行更新。

但是您所描述的情况并不是真正的问题-您想插入行,并且如果有冲突,则什么也不做。这里没有进行任何更新,因此它是一个简单的插入。

执行跳过所有冲突的插入是SQLAlchemy中的一件简单的事情(假设您已经将表定义为模型):

from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
engine = create_engine('your_db_connection_string', echo=True)
Session = sessionmaker(bind=engine)
session = Session()

# example column names
data = [{'col1': result.col1, 'col2': result.col2} 
        for result in session.query(table_b).all()]
insert_query = insert(table_a).values(data).on_conflict_do_nothing()

session.execute(insert_query)
session.commit()
session.close()