SQLAlchemy Core批量插入速度慢

时间:2016-09-12 17:18:03

标签: python postgresql orm sqlalchemy

我正在尝试截断一个表,并使用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
            )

2 个答案:

答案 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}

不确定是否允许链接,所以我将其置于破坏状态

  

ReadmePyPI

相关问题