Pandas: to_sql太慢

创建于 2017-02-01  ·  24评论  ·  资料来源: pandas-dev/pandas

代码示例

df_name.to_sql('table_name',
                          schema = 'public',
                          con = engine,
                          index = False,
                          if_exists = 'replace')

问题描述

我将500,000行数据帧写入Postgres AWS数据库,这需要非常非常长的时间才能将数据推送通过。

这是一个相当大的SQL Server,我的互联网连接非常好,因此我排除了造成问题的原因。

相比之下,csv2sql或在命令行上使用cat并管道传输到psql的速度要快得多。

IO SQL Usage Question

最有用的评论

将此代码添加到engine = create_engine(connection_string)

from sqlalchemy import event

@event.listens_for(e, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
    if executemany:
        cursor.fast_executemany = True
        cursor.commit()

在我的代码中, to_sql函数执行需要7分钟,现在只需要5秒;)

所有24条评论

参见此处: http :

使用SQLServer,您需要通过csv进行导入并批量上传以提高效率

您可能会发现这很有用: http :

ODO对我不起作用,它会产生我无法修复的错误,但是d6tstack可以正常工作https://github.com/d6t/d6tstack/blob/master/examples-sql.ipynb。 您可以使用熊猫进行预处理,它使用postgres COPY FROM来快速导入。 与RDS postgres一起很好地工作。

将此代码添加到engine = create_engine(connection_string)

from sqlalchemy import event

@event.listens_for(e, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
    if executemany:
        cursor.fast_executemany = True
        cursor.commit()

在我的代码中, to_sql函数执行需要7分钟,现在只需要5秒;)

谢谢@llautert!
这很有帮助!

# dont forget to import event
from sqlalchemy import event, create_engine

engine = create_engine(connection_string)

@event.listens_for(engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
    if executemany:
        cursor.fast_executemany = True
        cursor.commit()

我试图运行此修复程序,但遇到错误消息:

AttributeError: 'psycopg2.extensions.cursor' object has no attribute 'fast_executemany'

有人知道发生了什么吗?

嘿@ tim-sauchuk,也遇到了同样的错误,尽管我发现一个非常有效的解决方案,其中涉及对pandas.io.sql.py文件进行少量编辑(只需从__pycache__删除.pyc文件,然后再次导入)确保将新版本写入压缩文件)

https://github.com/pandas-dev/pandas/issues/8953

嘿@ tim-sauchuk,也遇到了同样的错误,尽管我发现一个非常有效的解决方案,其中涉及对pandas.io.sql.py文件进行少量编辑(只是在再次导入之前从pycache中删除.pyc文件)确保将新版本写入压缩文件)

8953

@ bsaunders23提到的问题#8953还显示了一种“猴子补丁”(在运行时修复)的方法。 我尝试了一下,一个20k的数据集上载了10余分钟,然后只花了4秒钟。

谢谢@llautert!
这很有帮助!

# dont forget to import event
from sqlalchemy import event, create_engine

engine = create_engine(connection_string)

@event.listens_for(engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
    if executemany:
        cursor.fast_executemany = True
        cursor.commit()

有谁知道我如何在带有self.engine实例的类中实现此解决方案?

有谁知道我如何在带有self.engine实例的类中实现此解决方案?

通过引用self.engine为我工作

例:

    self.engine = sqlalchemy.create_engine(connectionString, echo=echo)
    self.connection = self.engine.connect()

    @event.listens_for(self.engine, 'before_cursor_execute')
    def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
        print("Listen before_cursor_execute - executemany: %s" % str(executemany))
        if executemany:
            cursor.fast_executemany = True
            cursor.commit()

对我不起作用。 您正在使用什么熊猫和sqlalchemy版本?

我尝试运行sqlalchemy:1.2.4-py35h14c3975_0和1.2.11-py35h7b6447c_0

但我越来越

AttributeError:'psycopg2.extensions.cursor'对象没有属性'fast_executemany'

@ dean12 @llautert

在这种情况下,函数调用是什么样的? 换而言之,您使用什么参数来成功上传表?

<# dont forget to import event
from sqlalchemy import event, create_engine

engine = create_engine(connection_string)

@event.listens_for(engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
    if executemany:
        cursor.fast_executemany = True
        cursor.commit()>``

看到这里: https :

我尝试运行sqlalchemy:1.2.4-py35h14c3975_0和1.2.11-py35h7b6447c_0

但我越来越

AttributeError:'psycopg2.extensions.cursor'对象没有属性'fast_executemany'

您正在使用psycopg2,这是一个postgresql驱动程序。 此问题和修复与使用pyodbc驱动程序的Microsoft SQL Server有关。

如何添加“ dtype”参数

有谁知道我如何在带有self.engine实例的类中实现此解决方案?

通过引用self.engine为我工作

例:

    self.engine = sqlalchemy.create_engine(connectionString, echo=echo)
    self.connection = self.engine.connect()

    @event.listens_for(self.engine, 'before_cursor_execute')
    def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
        print("Listen before_cursor_execute - executemany: %s" % str(executemany))
        if executemany:
            cursor.fast_executemany = True
            cursor.commit()

你知道怎么了吗?

我认为正确的答案应该是使用https://docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2 -batch-mode-fast-execution,如果您要保存pandas dataframepostgres

熊猫的新版本包含method参数,可以将其选择为“多”。 这使代码运行得更快。

现在可以在一个步骤中执行fast_executemany (sqlalchemy> = 1.3.0):

engine = sqlalchemy.create_engine(connection_string, fast_executemany=True)

也许值得在文档中或示例中提及它? 这是一个与大熊猫无关的特殊案例,但它只是一小部分,在许多情况下都可以大大提高性能。

熊猫的新版本包含method参数,可以将其选择为“多”。 这使代码运行得更快。

您可能会认为,设置chunksize参数足以完成to_sql批处理插入,但不行。

MS SQL用户的替代方法是也使用turbodbc.Cursor.insertmanycolumns ,我已经在链接的StackOverflow帖子中解释了这一点: https ://stackoverflow.com/a/62671681/1689261

对于以后的读者来说,有两种选择可以将“ batch_mode”用于to_sql。 以下是这两种组合:

create_engine(connection_string, executemany_mode='batch', executemany_batch_page_size=x)

要么

create_engine(connection_string, executemany_mode='values', executemany_values_page_size=x)

这些参数的详细信息可以在这里找到: https: //docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2 -fast-execution-helpers

对于postgres用户,我建议将method设置为可调用对象:

可通过签名(pd_table,conn,keys,data_iter)调用:可用于基于特定的后端方言功能实现性能更高的插入方法。

并从此处的示例代码中调用该函数https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#insertion -method和

使用COPY FROM确实快很多faster

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

Ashutosh-Srivastav picture Ashutosh-Srivastav  ·  3评论

andreas-thomik picture andreas-thomik  ·  3评论

ebran picture ebran  ·  3评论

idanivanov picture idanivanov  ·  3评论

MatzeB picture MatzeB  ·  3评论