Solución:
Para la parte ‘escribir en el servidor SQL’, puede usar el conveniente to_sql
método de pandas (por lo que no es necesario iterar sobre las filas y realizar la inserción manualmente). Consulte los documentos sobre la interacción con bases de datos SQL con pandas: http://pandas.pydata.org/pandas-docs/stable/io.html#io-sql
Necesitará al menos pandas 0.14 para que esto funcione, y también necesita sqlalchemy
instalado. Un ejemplo, asumiendo df
es el DataFrame que obtuviste read_table
:
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)
Consulte también la página de documentación de to_sql
.
Más información sobre cómo crear el motor de conexión con sqlalchemy para el servidor sql con pyobdc, puede encontrar aquí: http: //docs.sqlalchemy.org/en/rel_1_1/dialects/mssql.html#dialect-mssql-pyodbc-connect
Pero si su objetivo es simplemente obtener los datos csv en la base de datos SQL, también podría considerar hacerlo directamente desde SQL. Consulte, por ejemplo, Importar archivo CSV en SQL Server
Versión de Python3 con una instancia SQL de LocalDB:
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()
Sí el bcp
La utilidad parece ser la mejor solución para la mayoría de los casos.
Si desea permanecer dentro de Python, el siguiente código debería funcionar.
from sqlalchemy import create_engine
import urllib
import pyodbc
quoted = urllib.parse.quote_plus("DRIVER={SQL Server};SERVER=YOURServerName;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")
No evites method='multi'
, porque reduce significativamente el tiempo de ejecución de la tarea.
A veces puede encontrar el siguiente error.
ProgrammingError: (‘42000’, ‘[42000] [Microsoft][ODBC SQL Server
Driver][SQL Server]La solicitud entrante tiene demasiados parámetros. El servidor admite un máximo de 2100 parámetros. Reducir el número de parámetros y reenviar la solicitud. (8003) (SQLExecDirectW) ‘)
En tal caso, determine la cantidad de columnas en su marco de datos: df.shape[1]
. Divida el número máximo de parámetros admitidos por este valor y use el piso del resultado como un tamaño de fragmento.