【问题标题】:Speed-up Pandas Dataframe insert into a Postgres DB using SQLAlchemy使用 SQLAlchemy 加速 Pandas Dataframe 插入 Postgres DB
【发布时间】:2017-11-15 00:34:45
【问题描述】:

我有一个大约 100k 行的 postgres 表。我提取了这个数据集并应用了一些转换,生成了一个包含 100K 行的新 pandas 数据框。现在我想将此数据框加载为数据库中的新表。我使用to_sql 使用 SQLAlchemy 连接将数据帧转换为 postgres 表。但是,这非常慢,需要几个小时。如何使用 SQLAlchemy 加快数据帧插入数据库表的速度?我想将插入速度从几个小时提高到几秒钟?有人可以帮我弄这个吗?

我在 Stackoverflow 上搜索过其他类似的问题。他们中的大多数将数据转换为 csv 文件,然后将copy_from 用于 sql。我正在寻找一种使用带有 pandas 数据框的 SQLAlchemy 批量插入语句的解决方案。

这是我的代码的一个小版本:

from sqlalchemy import * 
url = 'postgresql://{}:{}@{}:{}/{}'
url = url.format(user, password, localhost, 5432, db)
con = sqlalchemy.create_engine(url, client_encoding='utf8')
# I have a dataframe named 'df' containing 100k rows. I use the following code to insert this dataframe into the database table.
df.to_sql(name='new_table', con=con, if_exists='replace')

【问题讨论】:

  • 如果您提供一个小的可行代码示例,例如您将哪些参数传递给 to_sql() 方法,将更容易获得答案?
  • @suvy 我已经编辑了我的问题以包含示例代码。
  • 想知道这是否是测试是否是服务器的快速方法,尝试使用基于文件的数据库引擎 = create_engine('sqlite:///myfile.db') ,这同样慢吗?

标签: pandas dataframe sqlalchemy bulkinsert


【解决方案1】:

如果 pandas 版本高于 0.24,请尝试以下型号

支持 COPY FROM import csv from io import StringIO 的数据库的替代 to_sql() 方法

def psql_insert_copy(table, conn, keys, data_iter): # 获取一个可以提供游标的 DBAPI 连接 dbapi_conn = conn.connection 使用 dbapi_conn.cursor() 作为 cur: s_buf = StringIO() 作家 = csv.writer(s_buf) writer.writerows(data_iter) s_buf.seek(0)

    columns = ', '.join('"{}"'.format(k) for k in keys)
    if table.schema:
        table_name = '{}.{}'.format(table.schema, table.name)
    else:
        table_name = table.name

    sql = 'COPY {} ({}) FROM STDIN WITH CSV'.format(
        table_name, columns)
    cur.copy_expert(sql=sql, file=s_buf)

chunksize = 10 4 # 这取决于你的服务器配置。对于我的情况 104 ~10**5 是可以的。 df.to_sql('tablename',con=con, if_exists='replace',method=psql_insert_copy ,chunksize= chunksize)

如果您使用上述 psql_insert_copy 模式并且您的 postgresql 服务器正常工作,您应该享受飞行速度。

这是我的 ETL 速度。每批平均 280~300K 元组(以秒为单位)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 2020-09-10
    • 2019-11-24
    相关资源
    最近更新 更多