Conexión al servidor Microsoft SQL mediante Python


97

Estoy tratando de conectarme a SQL a través de Python para ejecutar algunas consultas en algunas bases de datos SQL en el servidor Microsoft SQL. De mi investigación en línea y en este foro, la biblioteca más prometedora parece ser pyodbc. Así que hice el siguiente código

import pyodbc
conn = pyodbc.connect(init_string="driver={SQLOLEDB}; server=+ServerName+; 
database=+MSQLDatabase+; trusted_connection=true")
cursor = conn.cursor()

y obtienes el siguiente error

Traceback (most recent call last):
  File "C:\Users...\scrap.py", line 3, in <module>
    conn = pyodbc.connect(init_string="driver={SQLOLEDB}; server=+ServerName+; database=+MSQLDatabase+; trusted_connection=true")
pyodbc.Error: ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')

He visto las siguientes publicaciones e intenté cambiar mi controlador a {sql server} y me he conectado usando enlaces ODBC antes en SAS, que es en parte en lo que se basa mi código anterior, así que no creo que necesite instalar nada más.

pyodbc.Error: ('IM002', '[IM002] [unixODBC] [Driver Manager] No se encontró el nombre de la fuente de datos y no se especificó ningún controlador predeterminado (0) (SQLDriverConnect)')

Pyodbc - "No se encontró el nombre de la fuente de datos y no se especificó ningún controlador predeterminado"

Gracias

Respuestas:


145

Así es como lo hago ...

import pyodbc 
cnxn = pyodbc.connect("Driver={SQL Server Native Client 11.0};"
                      "Server=server_name;"
                      "Database=db_name;"
                      "Trusted_Connection=yes;")


cursor = cnxn.cursor()
cursor.execute('SELECT * FROM Table')

for row in cursor:
    print('row = %r' % (row,))

Recursos relevantes:


61

Adición menor a lo dicho antes. Es probable que desee devolver un marco de datos. Esto se haría como

import pypyodbc 
import pandas as pd

cnxn = pypyodbc.connect("Driver={SQL Server Native Client 11.0};"
                        "Server=server_name;"
                        "Database=db_name;"
                        "uid=User;pwd=password")
df = pd.read_sql_query('select * from table', cnxn)

38

En las conexiones de fuentes de datos entre un cliente y un servidor, hay dos tipos generales: ODBC que usa un DRIVER y OLEDB que usa un PROVIDER. Y en el mundo de la programación, es un debate regular sobre qué ruta tomar para conectarse a las fuentes de datos.

Está utilizando un proveedor SQLOLEDB, pero lo especifica como controlador. Hasta donde yo sé, ni los módulos pyodbc ni pypyodbc admiten conexiones OLEDB de Windows. Sin embargo, el adodbapi hace que utilice Microsoft ADO como componente subyacente.

A continuación se muestran ambos enfoques para sus parámetros de conexión. Además, le doy formato a sus variables ya que su concatenación no rompió correctamente las comillas dentro de la cadena. Notarás que doblo las llaves ya que se necesita en la cadena de conexión y string.format()también la usa.

# PROVIDER
import adodbapi
conn = adodbapi.connect("PROVIDER=SQLOLEDB;Data Source={0};Database={1}; \
       trusted_connection=yes;UID={2};PWD={3};".format(ServerName,MSQLDatabase,username,password))
cursor = conn.cursor()

# DRIVER
import pyodbc
conn = pyodbc.connect("DRIVER={{SQL Server}};SERVER={0}; database={1}; \
       trusted_connection=yes;UID={2};PWD={3}".format(ServerName,MSQLDatabase,username,password))
cursor = conn.cursor()

Gracias por la explicación y el código, conseguí que el controlador funcionara. Aunque tuve que deshacerme del .format (...) y poner las variables en los lugares adecuados. ¿Qué estaba destinado a hacer el formato?
Christopher Ell

1
Necesita instalar adodbapipara usar la conexión OLEDB. Y el formato de cadena es la forma recomendada de pasar variables a una cadena en lugar de utilizar el +operador. Las llaves con números son marcadores de posición que se format()rellenan en consecuencia. Incluso puede pasar listas y tuplas usando format(). Su código original no dividió la cadena y las variables entre comillas, por lo que +se consideró parte de la cadena.
Parfait

4
Si bien esta respuesta es excelente y me ayudó a resolver el problema. Quien esté intentando hacerlo, recuerde que puede obtener una excepción si establece una conexión confiable = sí e ingresa el UID / pwd en la misma cadena de conexión. Esta es una combinación de una u otra y cuando usa una conexión confiable, su credencial de NT / sistema se usa para la autenticación, incluso si menciona explícitamente UID / PWD.
S4nd33p



4

Intente usar pytds, funciona en entornos más complejos pyodbcy más fáciles de configurar.

Lo hice funcionar en Ubuntu 18.04

Ref: https://github.com/denisenkom/pytds

Código de ejemplo en la documentación:

import pytds
with pytds.connect('server', 'database', 'user', 'password') as conn:
    with conn.cursor() as cur:
        cur.execute("select 1")
        cur.fetchall()

1
Gracias. Funciona como un encanto sin ninguna configuración compleja.
Shubham Patel

3

Seguir el código de Python funcionó para mí. Para verificar la conexión ODBC, primero creé una aplicación de consola C # de 4 líneas como se indica a continuación.

Código Python

import pandas as pd
import pyodbc 
cnxn = pyodbc.connect("Driver={SQL Server};Server=serverName;UID=UserName;PWD=Password;Database=RCO_DW;")
df = pd.read_sql_query('select TOP 10 * from dbo.Table WHERE Patient_Key > 1000', cnxn)
df.head()

Llamar a un procedimiento almacenado

 dfProcResult = pd.read_sql_query('exec dbo.usp_GetPatientProfile ?', cnxn, params=['MyParam'] )

Programa C # para verificar la conexión ODBC

    static void Main(string[] args)
    {
        string connectionString = "Driver={SQL Server};Server=serverName;UID=UserName;PWD=Password;Database=RCO_DW;";
        OdbcConnection cn = new OdbcConnection(connectionString);
        cn.Open();
        cn.Close();
    }

0

Un enfoque alternativo sería instalar Microsoft ODBC Driver 13, luego reemplazarSQLOLEDB conODBC Driver 13 for SQL Server

Saludos.


0

aquí está el que funciona para mí:

from sqlalchemy import create_engine
import urllib

conn_str = (
r'Driver=ODBC Driver 13 for SQL Server;'
r'Server=DefinitelyNotProd;'
r'Database=PlayPen;'
r'Trusted_Connection=Yes;')

quoted_conn_str = urllib.parse.quote_plus(conn_str)
engine = create_engine('mssql+pyodbc:///?odbc_connect={}'.format(quoted_conn_str))

0

Encontré recursos actualizados aquí: Microsoft | Documentos SQL | Controlador SQL de Python

Se explican estas dos opciones, incluidos todos los requisitos previos necesarios y ejemplos de código: controlador Python SQL - pyodbc (probado y funcionando) controlador Python SQL - pymssql


Hola, bienvenido a Stack Overflow. Debería intentar abordar la pregunta con algunas ideas (nuevas ideas en este caso). Algunas de su propio código o un nuevo enfoque. Luego use algunos enlaces para brindar más ayuda o respaldar su solución. No deberías simplemente publicar algunos enlaces.
Alex Leo

0

Mi version. Espero eso ayude.


import pandas.io.sql
import pyodbc
import sys

server = 'example'
db = 'NORTHWND'
db2 = 'example'

#Crear la conexión
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=' + server +
                      ';DATABASE=' + db +
                      ';DATABASE=' + db2 +
                      ';Trusted_Connection=yes')
#Query db
sql = """SELECT [EmployeeID]
      ,[LastName]
      ,[FirstName]
      ,[Title]
      ,[TitleOfCourtesy]
      ,[BirthDate]
      ,[HireDate]
      ,[Address]
      ,[City]
      ,[Region]
      ,[PostalCode]
      ,[Country]
      ,[HomePhone]
      ,[Extension]
      ,[Photo]
      ,[Notes]
      ,[ReportsTo]
      ,[PhotoPath]
  FROM [NORTHWND].[dbo].[Employees] """
data_frame = pd.read_sql(sql, conn)
data_frame

0

Intenté conectar el servidor SQL de las siguientes formas y me funcionaron.

Para conectarse usando la autenticación de Windows

import pyodbc

conn = pyodbc.connect('Driver={SQL Server};Server='+servername+';Trusted_Connection=yes;Database='+databasename+';')
cursor = conn.cursor()
cursor.execute("Select 1 as Data")

Para usar la autenticación del servidor SQL, utilicé el siguiente código.

import pyodbc

conn = pyodbc.connect('Driver={SQL Server};Server='+servername+  ';UID='+userid+';PWD='+password+';Database='+databasename) 
cursor1 = conn.cursor()
cursor1.execute("SELECT 1 AS DATA")

0

Prueba con pymssql:pip install pymssql

import pymssql

try:
    conn = pymssql.connect(server="host_or_ip", user="your_username", password="your_password", database="your_db")
    cursor = conn.cursor()
    cursor.execute ("SELECT @@VERSION")
    row = cursor.fetchone()
    print(f"\n\nSERVER VERSION:\n\n{row[0]}")
    cursor.close()
    conn.close()
except Exception:
    print("\nERROR: Unable to connect to the server.")
    exit(-1)

Salida:

SERVER VERSION:

Microsoft SQL Server 2016 (SP2-CU14) (KB4564903) - 13.0.5830.85 (X64)
        Jul 31 2020 18:47:07
        Copyright (c) Microsoft Corporation
        Standard Edition (64-bit) on Windows Server 2012 R2 Standard 6.3 <X64> (Build 9600: ) (Hypervisor)

La conexión también se puede comprobar desde el terminal, con una única línea de código con sqlcmd. Ver sintaxis .

╔═════════╦═════════════════════════════════════════╗
 Command                Description               
╠═════════╬═════════════════════════════════════════╣
   -S     [protocol:]server[instance_name][,port] 
   -U     login_id                                
   -p     password                                
   -Q     "cmdline query" (and exit)              
╚═════════╩═════════════════════════════════════════╝
sqlcmd -S "host_or_ip"  -U "your_username" -p -Q "SELECT @@VERSION"

salida:

Password:    your_password



--------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2016 (SP2-CU14) (KB4564903) - 13.0.5830.85 (X64) 
        Jul 31 2020 18:47:07 
        Copyright (c) Microsoft Corporation
        Standard Edition (64-bit) on Windows Server 2012 R2 Standard 6.3 <X64> (Build 9600: ) (Hypervisor)


(1 rows affected)

Network packet size (bytes): 4096
1 xact[s]:
Clock Time (ms.): total         1  avg   1.00 (1000.00 xacts per sec.)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.