Python >> Tutoriel Python >  >> Python Tag >> Linux

Authentification de Linux vers Windows SQL Server avec pyodbc

J'ai fini par utiliser la bibliothèque pymssql qui est essentiellement pyodbc au-dessus du pilote FreeTDS. Cela a fonctionné dès la sortie de la boîte.

Bizarre comme j'ai eu tant de mal à découvrir cette bibliothèque..


Vous devez obtenir un ticket Kerberos pour que cela fonctionne. Votre exemple ne précise pas si votre système Linux est configuré pour s'authentifier via Kerberos ou si vous avez déjà obtenu un ticket Kerberos avant que votre code n'atteigne votre chaîne de connexion.

Si votre système Linux est configuré pour s'authentifier via Kerberos, alors comme preuve de concept, vous pouvez obtenir un ticket Kerberos en utilisant kinit à partir de la ligne de commande. Voici ce qui fonctionne pour moi dans python3 exécuté dans Ubuntu sur Windows via le WSL. Le code python :

#!/usr/bin/env python

# minimal example using Kerberos auth
import sys
import re
import pyodbc

driver='{ODBC Driver 17 for SQL Server}'
server = sys.argv[1]
database = sys.argv[2]

# trusted_connection uses kerberos ticket and ignores UID and PASSWORD in connection string
# https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/using-integrated-authentication?view=sql-server-ver15

try:
    cnxn = pyodbc.connect(driver=driver, server=server, database=database, trusted_connection='yes')
    cursor = cnxn.cursor()
except pyodbc.Error as ex:
    msg = ex.args[1]
    if re.search('No Kerberos', msg):
        print('You must login using kinit before using this script.')
        exit(1)
    else:
        raise

# Sample select query
cursor.execute("SELECT @@version;")
row = cursor.fetchone()
while row:
    print(row[0])
    row = cursor.fetchone()
print('success')

Cela vous indique si vous n'avez pas de ticket. Puisqu'il utilise un ticket, vous n'avez pas besoin de spécifier un utilisateur ou un mot de passe dans le script. Il ignorera les deux.

Maintenant, nous l'exécutons :

[email protected]:~# kdestroy # make sure there are no active tickets
kdestroy: No credentials cache found while destroying cache

[email protected]:~# python pyodbc_sql_server_test.py tcp:dbserver.example.com mydatabase
You must login using kinit before using this script.

[email protected]:~# kinit
Password for [email protected]:

[email protected]:~# python pyodbc_sql_server_test.py tcp:dbserver.example.com mydatabase
Microsoft SQL Server 2016 (SP2-GDR) (KB4505220) - 13.0.5101.9 (X64)
        Jun 15 2019 23:15:58
        Copyright (c) Microsoft Corporation
        Enterprise Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: )

success

[email protected]:~#

Vous pouvez également réussir à obtenir un ticket Kerberos à partir du code python qui s'exécute avant d'établir cette connexion, mais cela dépasse le cadre de cette réponse. Une recherche de modules python Kerberos pourrait vous orienter vers une solution.

Il apparaît également possible de paramétrer le système Linux de manière à ce que dès qu'un utilisateur se connecte, il obtienne automatiquement un ticket Kerberos pouvant être transmis à d'autres processus. Cela sort également du cadre de cette réponse, mais une recherche de ticket Kerberos automatique lors de la connexion Linux peut fournir des indices.


Je trouve deux façons pour la même tâche. J'ai un serveur MSSQL avec authentification AD.

Vous pouvez utiliser JVM.Load et installer JAVA https://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html. Installez également JType1 version 0.6.3 pip install JPype==0.6.3 . La version supérieure à 0.6.3 ne fonctionnera pas correctement

import jaydebeapi
import pandas as pd
driver_name = "net.sourceforge.jtds.jdbc.Driver"
connection_url="jdbc:jtds:sqlserver://<server>:<port>/<database name>"
connection_properties = {
"domain": "<domain name>",
"user": "<username>",
"password": "<pwd>"}
jar_path =  <path to jsds>"/jtds-1.3.1.jar"
CONN = jaydebeapi.connect(driver_name, connection_url, connection_properties, jar_path)
sql = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS"
df = pd.read_sql(sql, CONN)

Cette version était trop lente pour moi.

Vous pouvez également utiliser pyodbc via FreeTDS . Pour créer une connexion FreeTDS Installez FreeTDS sur votre Linux apt-get install tdsodbc freetds-bin , configurez FreeTDS /etc/odbcinst.ini comme ceci :

[FreeTDS]
Description=FreeTDS
Driver=/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup=/usr/lib/x86_64-linux-gnu/odbc/libtdsS.so

et allumez-le odbcinst -i -d -f /etc/odbcinst.ini

Après cela, vous pouvez utiliser pyodbc

import pandas as pd
import pyodbc    
CONN =pyodbc.connect('DRIVER={FreeTDS};'
                                  'Server=<server>;'
                                  'Database=<database>;'
                                  'UID=<domain name>\\<username>;'
                                  'PWD=<password>;'
                                  'TDS_Version=8.0;'
                                  'Port=1433;')
sql = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS"
df = pd.read_sql(sql, CONN)

Cela fonctionne beaucoup plus rapidement