使用PYODBC将Pandas数据导入SQL服务器

r55awzrz  于 2023-04-04  发布在  其他
关注(0)|答案(9)|浏览(258)

我试图了解如何python可以拉数据从FTP服务器到pandas,然后将其移动到SQL Server.我的代码在这里是非常基本的,至少可以说,我正在寻找任何建议或帮助在所有.我已经尝试从FTP服务器加载数据第一,它的工作正常...如果我删除这段代码并将其更改为select from ms sql server,则连接字符串可以正常工作,但插入到SQL server中似乎会导致问题。

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代码这运行完美,但我不明白如何使下一个跳转到微软SQL服务器,或即使它是可能的,而不保存到一个文件第一。

xeufq47z

xeufq47z1#

对于“写入sql server”部分,可以使用pandas方便的to_sql方法(因此不需要迭代行并手动执行插入)。请参阅使用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)

另请参阅to_sql的文档页面。
有关如何使用sqlalchemy为sql server和pyobdc创建连接引擎的更多信息,您可以在这里找到:http://docs.sqlalchemy.org/en/rel_1_1/dialects/mssql.html#dialect-mssql-pyodbc-connect
但是如果您的目标只是将csv数据放入SQL数据库,那么您也可以考虑直接从SQL执行此操作。

8fsztsew

8fsztsew2#

使用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()
mrwjdhj3

mrwjdhj33#

是的,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',因为它会显著减少任务的执行时间。
有时您可能会遇到以下错误。
编程错误:('42000 ','[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]传入请求的参数太多。服务器最多支持2100个参数。请减少参数数并重新发送请求。(8003)(SQLExecDirectW)')
在这种情况下,确定 Dataframe 中的列数:df.shape[1]。将支持的最大参数数除以此值,并使用结果的floor作为块大小。

ef1yzkbh

ef1yzkbh4#

我发现当你有一个大的数据集时,使用bcp实用程序(https://learn.microsoft.com/en-us/sql/tools/bcp-utility)效果最好。我有270万行,插入速度为80 K行/秒。你可以将 Dataframe 存储为csv文件(如果你的数据没有制表符和utf8编码,使用制表符作为分隔符)。使用bcp,我使用了格式“-c”,到目前为止它没有问题。

hc8w905p

hc8w905p5#

这在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')
4sup72z8

4sup72z86#

由于Connection代表数据库的开放资源,因此我们希望始终将此对象的使用范围限制在特定的上下文中,最好的方法是使用Python上下文管理器表单,也称为with语句。
那么这个例子就是

from sqlalchemy import create_engine
import urllib
import pyodbc
connection_string = (
    "Driver={SQL Server Native Client 11.0};"
    "Server=myserver;"
    "UID=myuser;"
    "PWD=mypwd;"
    "Database=mydb;"
)
quoted = urllib.parse.quote_plus(connection_string)
engine = create_engine(f'mssql+pyodbc:///?odbc_connect={quoted}')
with engine.connect() as cnn:
    df.to_sql('mytable',con=cnn, if_exists='replace', index=False)
nkhmeac6

nkhmeac67#

下面是我使用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的索引值。

3hvapo4f

3hvapo4f8#

# using class function   
import pandas as pd
import pyodbc
import sqlalchemy
import urllib
class data_frame_to_sql():    
   def__init__(self,dataFrame,sql_table_name):
           self.dataFrame=dataFrame
           self.sql_table_name=sql_table_name
           def conversion(self):
       
           params = urllib.parse.quote_plus("DRIVER={SQL Server};"
                                            "SERVER=######;"
                                            "DATABASE=####;"
                                            "UID=#####;"
                                            "PWD=###;")
       
       
           try:
               engine = sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect={}".format(params))
               return f"Table '{self.sql_table_name}' added sucsessfully in database" ,self.dataFrame.to_sql(self.sql_table_name, engine)
       
           except Exception as e :
               e=str(e).replace(".","")
               print(f"{e} in Database." )

data={"BusinessEntityID":["1","2","3"],"FirstName":["raj","abhi","amir"],"LastName":["kapoor","bachn","khhan"]}
df = pd.DataFrame(data, columns= ['BusinessEntityID','FirstName','LastName'])
ab=data_frame_to_sql(df,"ab").conversion()
print(ab)
xmd2e60i

xmd2e60i9#

不一定要使用sqlamchemy,可以直接创建一个与pyodbc的连接来使用pandas,如下所示:

with pyodbc.connect('DRIVER={ODBC Driver 18 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password) as newconn:
    df = pd.read_sql(<your sql goes here>,newconn)

相关问题