【问题标题】:to_sql() inserting row by row despite fast_executemany=True in create_engine()尽管在 create_engine() 中 fast_executemany=True,to_sql() 仍逐行插入
【发布时间】:2021-06-06 14:39:33
【问题描述】:

我有一个场景,我需要在表之间进行批量插入,我配置了我的 sqlalchemy 引擎来做到这一点。我配置为在每个块中进行批量插入( chunksize: 10000 ),但我仍然逐行插入。

destengine = sqlalchemy.create_engine(
               "mssql+pyodbc://"+destuser+":"+destpass+"@"+destaddress+""+destdatabase+"?driver=ODBC+Driver+17+for+SQL+Server", echo=False, fast_executemany = True)

for chunk in pd.read_sql( selectquery, srcconnection, chunksize=100000):
    chunk.to_sql("MyTable", destengine, if_exists='append', index = False )

如上所述,我在我的连接字符串中选择了 ODBC 驱动程序作为 ODBC 驱动程序 17,我在我的引擎中将 fast_executemany 设置为 true。我究竟做错了什么?我的表有数百万行和 100 多列。我是 Pandas 的新手,但我认为我所做的与示例相同。

【问题讨论】:

  • 感谢@GordThompson 的评论,但在这种情况下,插入是通过查询进行的,并且具有光标和对 executemany() 函数的调用。在我的情况下,我使用 sqlalchemy 的 to_sql() 来进行插入。我这样做是因为我有 100 多列,所以在代码中编写插入查询会很困难而且很难看

标签: python sql-server pandas sqlalchemy pyodbc


【解决方案1】:

你发现了这个的变体:

fast_executemany ineffective when generator passed to executemany

pandas 文档指出,如果将 chunksize= 传递给 read_sql(),那么它会返回一个迭代器而不是 DataFrame。我们可以通过将结果拉入一个“真实的”DataFrame 并在其上调用to_sql() 来解决这个问题:

for chunk in pd.read_sql( selectquery, srcconnection, chunksize=10):
    df = pd.DataFrame(chunk.values, columns=chunk.columns)
    df.to_sql("MyTable", destengine, if_exists='append', index = False )

【讨论】:

  • 感谢您的回答。我这样做了,我在 sql server 中的跟踪现在显示增加了 'sp_execute' ( sp_execute 40 ex ) 数字,之前不是。但是......插入仍然没有批量插入,逐行进行。每个“sp_execute number”中有数百个插入,但逐行插入。我在 Microsoft SSIS 中运行相同的流程,并且 SSIS 的速度提高了 50 倍以上。在 Panda 中,我每秒的行数不到 1000 行
  • 如果您正在查看 SQL Profiler 中的跟踪,那么fast_executemany=True 的样子就是:一个sp_prepare,然后是一堆sp_execute 调用。它不会做BULK INSERT。对于非常大的插入,将 DataFrame 转储到 CSV 文件并调用 bcp 实用程序可能会更快。
  • 再次感谢您,我认为 executemany 会进行批量插入。那么,传递数据以使用另一个库,在插入数据库之前在硬盘驱动程序中传递文件比直接在内存中工作更快吗?我很惊讶。我来自 C++ 和 SSIS,我从 Python 开始,我不知道这个'bcp',谢谢你的提示!仅使用 SQLAlchemy 引擎和 Pandas 就不可能以简单的方式进行批量插入吗?
  • 在服务器上运行BULK INSERT 要求输入文件也对服务器“可见”(本地文件或服务器可以“看到”的网络共享上)。大多数生产 SQL Server 都没有配置为也允许文件上传(至少在我的经验中没有)。
  • 即使文章称“批量插入”什么不是批量插入naysan.ca/2020/05/09/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-25
  • 2021-04-20
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
相关资源
最近更新 更多