使用SQLAlchemy将Pandas数据框加速插入Postgres DB

问题描述 投票:0回答:1

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

我已经搜索了关于Stackoverflow的其他类似问题。它们中的大多数将数据转换为csv文件,然后对SQL使用copy_from。我正在寻找将SQLAlchemy批量插入语句与pandas数据框一起使用的解决方案。

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

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')
pandas dataframe sqlalchemy bulkinsert
1个回答
0
投票

如果熊猫版本高于0.24,请尝试以下模型

对于支持从io import StringIO导入CSV的COPY FROM的数据库的替代to_sql()方法

def psql_insert_copy(table,conn,keys,data_iter):#获取可以提供游标的DBAPI连接dbapi_conn =连接使用dbapi_conn.cursor()作为cur:s_buf = StringIO()writer = 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#它取决于您的服务器配置。对于我的情况10 4〜10 ** 5是可以的。df.to_sql('tablename',con = con,if_exists ='replace',method = psql_insert_copy,chunksize = chunksize)

如果您在以上psql_insert_copy模式下使用,并且您的Postgresql服务器正常工作,则应享受飞行速度。

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

© www.soinside.com 2019 - 2024. All rights reserved.