我正在尝试截断一个表,并使用SQLAlchemy仅插入~3000行数据,而且速度很慢(约10分钟)。
我按照这个doc的建议并利用sqlalchemy核心来完成我的插入,但它仍然运行得非常慢。我可能会看到什么可能的罪魁祸首?数据库是postgres RDS实例。谢谢!
engine = sa.create_engine(db_string, **kwargs, pool_recycle=3600)
with engine.begin() as conn:
conn.execute("TRUNCATE my_table")
conn.execute(
MyTable.__table__.insert(),
data #where data is a list of dicts
)
答案 0 :(得分:5)
当我看到它没有答案时,我感到很沮丧...前几天我遇到了完全相同的问题:尝试使用CORE将大约数百万行批量插入到Postgres RDS实例中。这是小时。
作为一种解决方法,我最终编写了自己的批量插入脚本,该脚本生成了原始的sql本身:
bulk_insert_str = []
for entry in entry_list:
val_str = "('{}', '{}', ...)".format(entry["column1"], entry["column2"], ...)
bulk_insert_str.append(val_str)
engine.execute(
"""
INSERT INTO my_table (column1, column2 ...)
VALUES {}
""".format(",".join(bulk_insert_str))
)
虽然丑陋,但这给了我们所需的性能(~500,000行/分钟)
您找到了基于CORE的解决方案吗?如果没有,希望这有帮助!
更新:结束将我的旧脚本移动到我们未使用的备用EC2实例中,这实际上修复了性能缓慢的问题。不确定您的设置是什么,但显然从外部(非AWS)连接与RDS通信时存在网络开销。
答案 1 :(得分:0)
前一段时间,我在公司工作时一直在为这个问题而苦苦挣扎,因此我们创建了一个具有批量插入和更新功能的库。希望我们已考虑到所有性能和安全性问题。该库是开源的,可在PyPI上使用,名称为bulky
。
让我向您展示一些用法示例:
插入:
import bulky
from your.sqlalchemy.models import Model
from your.sqlalchemy.session import Session
data = [
{Model.column_float: random()}
for _ in range(100_000_000)
]
rows_inserted = bulky.insert(
session=Session,
table_or_model=Model,
values_series=data,
returning=[Model.id, Model.column_float]
)
new_items = {row.id: row.column_float for row in rows_inserted}
更新:
import bulky
from your.sqlalchemy.models import ManyToManyTable
from your.sqlalchemy.session import Session
data = [
{
ManyToManyTable.fk1: i,
ManyToManyTable.fk2: j,
ManyToManyTable.value: i + j,
}
for i in range(100_000_000)
for j in range(100_000_000)
]
rows_updated = bulky.update(
session=Session,
table_or_model=ManyToManyTable,
values_series=data,
returning=[
ManyToManyTable.fk1,
ManyToManyTable.fk2,
ManyToManyTable.value,],
reference=[
ManyToManyTable.fk1,
ManyToManyTable.fk2,],
)
updated_items = {(row.fk1, row.fk2): row.value for row in rows_updated}
不确定是否允许链接,所以我将其置于破坏状态