使用PYODBC从pandas获取数据到SQL服务器

时间:2014-09-04 09:23:11

标签: python sql pandas pyodbc

我试图了解python如何将数据从FTP服务器拉入pandas然后将其移动到SQL Server中。我的代码至少可以说是非常简陋的,我正在寻找任何建议或帮助。我试图从FTP服务器首先加载数据工作正常....如果我然后删除此代码并将其更改为从ms sql服务器中选择它是好的,所以连接字符串工作,但插入到SQL服务器似乎造成了问题。

import pyodbc
import pandas
from ftplib import FTP
from StringIO import StringIO
import csv

ftp = FTP ('ftp.xyz.com','user','pass' )
ftp.set_pasv(True)
r = StringIO()
ftp.retrbinary('filname.csv', r.write)

pandas.read_table (r.getvalue(), delimiter=',')


connStr = ('DRIVER={SQL Server Native Client 10.0};SERVER=localhost;DATABASE=TESTFEED;UID=sa;PWD=pass')
conn = pyodbc.connect(connStr)

cursor = conn.cursor()
cursor.execute("INSERT INTO dbo.tblImport(Startdt, Enddt, x,y,z,)" "VALUES                  (x,x,x,x,x,x,x,x,x,x.x,x)")
cursor.close()
conn.commit()
conn.close()
print"Script has successfully run!"

当我删除ftp代码时,它运行得很好,但是我不明白如何进行下一次跳转以将其转换为Microsoft SQL服务器,或者即使可以先将其保存到文件中也是如此。

6 个答案:

答案 0 :(得分:30)

用于写入sql server'另外,您可以使用方便的to_sql pandas方法(因此无需迭代行并手动执行插入)。请参阅有关使用pandas与SQL数据库交互的文档:http://pandas.pydata.org/pandas-docs/stable/io.html#io-sql

您需要至少pandas 0.14才能使其正常工作,并且还需要安装sqlalchemy。假设df是从read_table获得的DataFrame:

,例如
import sqlalchemy
import pyodbc
engine = sqlalchemy.create_engine("mssql+pyodbc://<username>:<password>@<dsnname>")

# write the DataFrame to a table in the sql database
df.to_sql("table_name", engine)

另见documentation page of to_sql 有关如何使用pyobdc为sql server创建sqlalchemy连接引擎的更多信息,您可以在这里找到:http://docs.sqlalchemy.org/en/rel_1_1/dialects/mssql.html#dialect-mssql-pyodbc-connect


但是如果您的目标是将csv数据放入SQL数据库,您也可以考虑直接从SQL执行此操作。参见例如Import CSV file into SQL Server

答案 1 :(得分:5)

是的,bcp实用程序似乎是大多数情况下的最佳解决方案。

如果您想保留在Python中,则以下代码应该有效。

from sqlalchemy import create_engine
import urllib
import pyodbc

quoted = urllib.parse.quote_plus("DRIVER={SQL Server};SERVER=YOUR\ServerName;DATABASE=YOur_Database")
engine = create_engine('mssql+pyodbc:///?odbc_connect={}'.format(quoted))

df.to_sql('Table_Name', schema='dbo', con = engine, chunksize=200, method='multi', index=False, if_exists='replace')

请避免使用method='multi',因为它会大大减少任务执行时间。

有时您可能会遇到以下错误。

ProgrammingError :(“ 42000”,“ [42000] [Microsoft] [ODBC SQL Server 驱动程序] [SQL Server]传入请求的参数太多。的 服务器最多支持2100个参数。减少数量 参数并重新发送请求。 (8003)(SQLExecDirectW)')

在这种情况下,请确定数据框中的列数:df.shape[1]。将支持的最大参数数量除以该值,然后将结果的下限用作块大小。

答案 2 :(得分:2)

我发现使用bcp实用程序(https://docs.microsoft.com/en-us/sql/tools/bcp-utility)在拥有大型数据集时效果最佳。我有270万行以80K行/秒的速度插入。您可以将数据框存储为csv文件(如果您的数据没有标签和utf8编码,请使用制表符分隔符)。使用bcp,我已经使用了格式&#34; -c&#34;到目前为止它没有问题。

答案 3 :(得分:1)

使用LocalDB SQL实例的Python3版本:

from sqlalchemy import create_engine
import urllib
import pyodbc
import pandas as pd

df = pd.read_csv("./data.csv")

quoted = urllib.parse.quote_plus("DRIVER={SQL Server Native Client 11.0};SERVER=(localDb)\ProjectsV14;DATABASE=database")
engine = create_engine('mssql+pyodbc:///?odbc_connect={}'.format(quoted))

df.to_sql('TargetTable', schema='dbo', con = engine)

result = engine.execute('SELECT COUNT(*) FROM [dbo].[TargetTable]')
result.fetchall()

答案 4 :(得分:0)

这对我适用于Python 3.5.2:

import sqlalchemy as sa
import urllib
import pyodbc

conn= urllib.parse.quote_plus('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
engine = sa.create_engine('mssql+pyodbc:///?odbc_connect={}'.format(conn))

frame.to_sql("myTable", engine, schema='dbo', if_exists='append', index=False, index_label='myField')

答案 5 :(得分:0)

以下是使用 sqlalchemy 对我有用的方法。注意最后一部分 ?driver=SQL+Server'

import sqlalchemy
import pyodbc
engine = sqlalchemy.create_engine('mssql+pyodbc://MyUser:MyPWD@dataserver.sandbox.myserver/MY_DB?driver=SQL+Server')
dt.to_sql("PatientResultTest", engine,if_exists='append')

SQL 表的开头需要一个 index 列来存储 dataframe 的索引值。