为什么在微型 df 上出现 fast_executemany 的内存错误?
Why would I get a memory error with fast_executemany on a tiny df?
我正在寻找加快将数据帧推送到 sql 服务器的方法,偶然发现了一种方法 这种方法在速度方面让我大吃一惊。使用普通 to_sql
花了将近 2 个小时,而这个脚本在 12.54 秒内完成,以推送 100k 行 X 100 列 df。
因此,在使用样本 df 测试了下面的代码之后,我尝试使用具有许多不同数据类型(int、字符串、浮点数、布尔值)的 df。但是,我很难过看到内存错误。所以我开始减小我的 df 的大小以查看限制是什么。我注意到,如果我的 df 有任何字符串,那么我将无法加载到 sql 服务器。我无法进一步隔离问题。下面的脚本取自 link 中的问题,但是,我添加了一个带字符串的小 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。
我在 32 位上遇到了这个问题,并将我的中断器切换到 64 位,这解决了我的内存问题。除了该解决方案之外,我建议将您处理的数据量分块。您可以建立阈值,一旦达到该阈值,您就可以处理该数据块并进行迭代,直到处理完所有数据。
我正面临这个问题。
通过更改解决:
conn = "DRIVER={SQL Server};SERVER=SERVER_IP;DATABASE=DB_NAME;UID=USER_ID;PWD=PWD"
为此:
conn = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=SERVER_IP;DATABASE=DB_NAME;UID=USER_ID;PWD=PWD"
我正在寻找加快将数据帧推送到 sql 服务器的方法,偶然发现了一种方法 to_sql
花了将近 2 个小时,而这个脚本在 12.54 秒内完成,以推送 100k 行 X 100 列 df。
因此,在使用样本 df 测试了下面的代码之后,我尝试使用具有许多不同数据类型(int、字符串、浮点数、布尔值)的 df。但是,我很难过看到内存错误。所以我开始减小我的 df 的大小以查看限制是什么。我注意到,如果我的 df 有任何字符串,那么我将无法加载到 sql 服务器。我无法进一步隔离问题。下面的脚本取自 link 中的问题,但是,我添加了一个带字符串的小 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。
我在 32 位上遇到了这个问题,并将我的中断器切换到 64 位,这解决了我的内存问题。除了该解决方案之外,我建议将您处理的数据量分块。您可以建立阈值,一旦达到该阈值,您就可以处理该数据块并进行迭代,直到处理完所有数据。
我正面临这个问题。
通过更改解决:
conn = "DRIVER={SQL Server};SERVER=SERVER_IP;DATABASE=DB_NAME;UID=USER_ID;PWD=PWD"
为此:
conn = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=SERVER_IP;DATABASE=DB_NAME;UID=USER_ID;PWD=PWD"