Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么在一个很小的df上使用fast_ExecuteMy时会出现内存错误?_Python_Sql Server_Pandas_Sqlalchemy_Pyodbc - Fatal编程技术网

Python 为什么在一个很小的df上使用fast_ExecuteMy时会出现内存错误?

Python 为什么在一个很小的df上使用fast_ExecuteMy时会出现内存错误?,python,sql-server,pandas,sqlalchemy,pyodbc,Python,Sql Server,Pandas,Sqlalchemy,Pyodbc,我在寻找加速将数据帧推送到sql server的方法,偶然发现了一种方法,这种方法在速度上让我大吃一惊。使用normalto_sql几乎花费了2个小时,这个脚本在12.54秒内完成,以推送100k行X 100列df 因此,在使用示例df测试下面的代码之后,我尝试使用具有许多不同数据类型(int、string、float、boolean)的df。然而,看到一个记忆错误,我很难过。因此,我开始缩小df的大小,以了解其局限性。我注意到,如果我的df有任何字符串,那么我就无法加载到sqlserver。我

我在寻找加速将数据帧推送到sql server的方法,偶然发现了一种方法,这种方法在速度上让我大吃一惊。使用normal
to_sql
几乎花费了2个小时,这个脚本在12.54秒内完成,以推送100k行X 100列df

因此,在使用示例df测试下面的代码之后,我尝试使用具有许多不同数据类型(int、string、float、boolean)的df。然而,看到一个记忆错误,我很难过。因此,我开始缩小df的大小,以了解其局限性。我注意到,如果我的df有任何字符串,那么我就无法加载到sqlserver。我很难进一步孤立这个问题。下面的脚本取自链接中的问题,但是,我添加了一个带有字符串的小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=SQL Server的ODBC驱动程序11
也失败了,因为

函数序列错误(0)(SQLParamData)

这与GitHub上现有的pyodbc问题有关。我公布了我的调查结果

这一问题仍在调查中。在此期间,您可以通过

  • 使用较新的ODBC驱动程序,如SQL Server的
    driver=ODBC驱动程序13
  • 运行
    pip安装pyodbc==4.0.22
    以使用早期版本的pyodbc

我在32位时遇到了这个问题,并将中断器切换到64位,从而解决了我的内存问题。除此之外,我建议您将处理的数据量分块。您可以建立阈值,一旦达到阈值,您就可以处理该数据块并进行迭代,直到处理完所有数据。

谢谢!pyodbc 4.0.22对我不起作用,但pyodbc 4.0.19运行良好。另外,我注意到脚本在将数据类型添加到
to_sql
语句时抛出了一个错误。因此,我只需将数据加载到SQL Server并在那里更改数据类型,以防有人遇到相同的错误。谢谢@MartinBobak,这是一个非常奇怪的错误。。!我不得不摆弄元数据,它工作了,但很烦人。还发现性能提升惊人。