Connessione a Microsoft SQL Server utilizzando Python


97

Sto cercando di connettermi a SQL tramite python per eseguire alcune query su alcuni database SQL su Microsoft SQL server. Dalle mie ricerche online e su questo forum la libreria più promettente sembra essere pyodbc. Quindi ho creato il seguente codice

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

e ottieni il seguente errore

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)')

Ho guardato i seguenti post e ho provato a cambiare il mio driver in {sql server} e mi sono connesso utilizzando collegamenti ODBC prima in SAS, che è in parte quello su cui si basa il mio codice sopra, quindi non credo di aver bisogno di installare nient'altro.

pyodbc.Error: ('IM002', '[IM002] [unixODBC] [Driver Manager] Nome origine dati non trovato e nessun driver predefinito specificato (0) (SQLDriverConnect)')

Pyodbc - "Nome origine dati non trovato e nessun driver predefinito specificato"

Grazie

Risposte:


145

Ecco come lo faccio ...

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,))

Risorse rilevanti:


61

Minore aggiunta a quanto detto prima. Probabilmente vorrai restituire un dataframe. Questo sarebbe fatto come

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

Nelle connessioni origine dati tra un client e un server ci sono due tipi generali: ODBC che utilizza un DRIVER e OLEDB che utilizza un PROVIDER. E nel mondo della programmazione, è un dibattito regolare su quale percorso seguire per connettersi alle fonti di dati.

Stai usando un provider SQLOLEDB, ma lo specifichi come driver. Per quanto ne so, né i moduli pyodbc né pypyodbc supportano le connessioni Window OLEDB. Tuttavia, l' adodbapi fa che utilizza Microsoft ADO come componente sottostante.

Di seguito sono riportati entrambi gli approcci per i parametri di connessione. Inoltre, formatto stringa le tue variabili poiché la tua concatenazione non ha interrotto correttamente le virgolette all'interno della stringa. Noterai che raddoppio le parentesi graffe poiché è necessario nella stringa di connessione e string.format()lo usa anche.

# 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()

Grazie per la spiegazione e il codice, ho fatto funzionare il driver. Anche se ho dovuto sbarazzarmi del .format (...) e mettere le variabili al posto giusto. Qual era il formato destinato a fare?
Christopher Ell

1
È necessario installare adodbapiper utilizzare la connessione OLE DB. E il formato stringa è il modo consigliato per passare le variabili in una stringa anziché utilizzare l' +operatore. Le parentesi graffe con i numeri sono segnaposto che si format()riempiono di conseguenza. Puoi anche passare elenchi e tuple usando format(). Il codice originale non interrompeva la stringa e le variabili tra virgolette, quindi +era considerato parte della stringa.
Parfait

4
Anche se questa risposta è ottima e mi ha aiutato a risolvere il problema. chiunque stia tentando di farlo ricorda che potresti ricevere un'eccezione se imposti la connessione fidata = yes e inserisci l'UID / pwd nella stessa stringa di connessione. Questa è una combinazione o / o e quando si utilizza una connessione fidata, le credenziali di sistema / NT vengono utilizzate per l'autenticazione anche se si menziona esplicitamente UID / PWD.
S4nd33p



4

Prova a usare pytds, funziona in un ambiente più complesso pyodbce più facile da configurare.

L'ho fatto funzionare su Ubuntu 18.04

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

Codice di esempio nella documentazione:

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

1
Grazie. Funziona come un fascino senza alcuna configurazione complessa.
Shubham Patel

3

Seguire il codice Python ha funzionato per me. Per verificare la connessione ODBC, ho prima creato un'applicazione console C # a 4 righe come elencato di seguito.

Codice 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()

Chiamare una stored procedure

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

Programma C # per controllare la connessione 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 approccio alternativo potrebbe essere l' installazione del driver Microsoft ODBC 13, quindi la sostituzione SQLOLEDBconODBC Driver 13 for SQL Server

Saluti.


0

ecco quello che funziona per me:

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

Ho trovato risorse aggiornate qui: Microsoft | Documenti SQL | Driver SQL Python

Sono spiegate queste due opzioni, inclusi tutti i prerequisiti necessari ed esempi di codice: driver SQL Python - pyodbc (testato e funzionante) driver SQL Python - pymssql


Ciao - Benvenuto in Stack Overflow - dovresti mirare ad affrontare la domanda con alcune idee (nuove idee in questo caso) - Alcuni del tuo codice o un nuovo approccio. Quindi utilizzare alcuni collegamenti per fornire ulteriore assistenza o eseguire il backup della soluzione. Non dovresti solo pubblicare alcuni link.
Alex Leo

0

La mia versione. Spero che sia d'aiuto.


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

Ho provato a connettere il server sql nei seguenti modi e quelli hanno funzionato per me.

Per connettersi utilizzando l'autenticazione di 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")

Per utilizzare l'autenticazione del server sql ho usato il seguente codice.

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

Prova 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)

Produzione:

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)

Il collegamento può essere verificato anche da terminale, con una sola riga di codice con sqlcmd. Vedi sintassi .

╔═════════╦═════════════════════════════════════════╗
 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"

produzione:

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.)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.