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

Christopher Ell
fuente

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:

CENIZA
fuente
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)
Keith
fuente
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()
Parfait
fuente
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
13

Aquí hay algunas fotos para principiantes.

ingrese la descripción de la imagen aquí

Andrés
fuente
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()
Alfred Huang
fuente
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();
    }
LCJ
fuente
0

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

Saludos.

mondieki
fuente
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))
James
fuente
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

Karl
fuente
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
Jose garcia
fuente
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")
SRK_124
fuente
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.)
Milovan Tomašević
fuente