python - 为什么在微型 df 上使用 fast_executemany 会出现内存错误?

标签 python sql-server pandas sqlalchemy pyodbc

我正在寻找加速将数据帧推送到 sql server 的方法,并偶然发现了一种方法 here.这种方法在速度方面让我震惊。使用普通的 to_sql 花费了将近 2 个小时,而这个脚本在 12.54 秒内完成以推送 100k 行 X 100 列 df。

因此,在使用样本 df 测试了下面的代码之后,我尝试使用具有许多不同数据类型(int、string、floats、Booleans)的 df。但是,我很难过看到内存错误。所以我开始减小我的 df 的大小以查看限制是什么。我注意到如果我的 df 有任何字符串,那么我将无法加载到 sql server。我无法进一步隔离问题。下面的脚本取自链接中的问题,但是,我添加了一个带有字符串的小 df。任何关于如何纠正此问题的建议都会很棒!

import pandas as pd
import numpy as np
import time
from sqlalchemy import create_engine, event
from urllib.parse import quote_plus
import pyodbc

conn =  "DRIVER={SQL Server};SERVER=SERVER_IP;DATABASE=DB_NAME;UID=USER_ID;PWD=PWD"
quoted = quote_plus(conn)
new_con = 'mssql+pyodbc:///?odbc_connect={}'.format(quoted)
engine = create_engine(new_con)


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


table_name = 'fast_executemany_test'
df1 = pd.DataFrame({'col1':['tyrefdg','ertyreg','efdgfdg'],
                   'col2':['tydfggfdgrefdg','erdfgfdgfdgfdgtyreg','edfgfdgdfgdffdgfdg']
                   })



s = time.time()
df1.to_sql(table_name, engine, if_exists = 'replace', chunksize = None)
print(time.time() - s)

最佳答案

我能够使用 pyodbc 4.0.23 重现您的问题。 MemoryError 与您使用古老的

有关
DRIVER={SQL Server}

进一步测试使用

DRIVER=ODBC Driver 11 for SQL Server

也失败了,有

Function sequence error (0) (SQLParamData)

这与 GitHub 上现有的 pyodbc 问题有关。我发布了我的发现here .

该问题仍在调查中。在此期间,您可以继续进行

  • 使用更新的 ODBC 驱动程序,例如 DRIVER=ODBC Driver 13 for SQL Server
  • 运行 pip install pyodbc==4.0.22 以使用早期版本的 pyodbc。

关于python - 为什么在微型 df 上使用 fast_executemany 会出现内存错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49887717/

相关文章:

Python-按组计算连续频率

python - Numpy - 将第一行作为名称立即加载到结构化数组中?

python - 获取列表列表中每个元素的索引并制作字典

python - 使用 pandas 将多个数据框合并在一起

python - 检查值列表中的对象

sql - 返回子记录等于特定值的父记录,并且给定父记录的总子记录集等于特定值

python - 从现有 MongoDB 数据库创建 Django 模型

c# - ExecuteNonQuery 在 C# 中不起作用

sql - 具有最小和最大条件的交叉连接

python - 根据最后一行值过滤列