Connecter Python et pyodbc à Azure Databricks

Vous pouvez vous connecter depuis votre code Python local via ODBC aux données d’un cluster Azure Databricks ou d’un entrepôt SQL. Pour ce faire, vous pouvez utiliser le module pyodbc Open source Python code.

Suivez ces instructions pour installer, configurer et utiliser pyodbc.

Pour plus d’informations sur pyodbc, consultez le Wiki pyodbc.

Notes

Databricks offre le connecteur Databricks SQL pour Python comme alternative à pyodbc. Le connecteur Databricks SQL pour Python est plus facile à configurer et à utiliser, et dispose d’un ensemble plus robuste de constructions de codage, que pyodbc . Cependant pyodbc peut avoir de meilleures performances lors de la récupération de résultats de requêtes de plus de 10 Mo.

Ces instructions ont été testées avec le pilote ODBC Databricks 2.7.5, pyodbc 5.0.1 et unixODBC 2.3.12.

Spécifications

Étape 1 : télécharger, installer et configurer des logiciels

Dans cette étape, vous téléchargez et installez le pilote ODBC Databricks, le package unixodbc et le module pyodbc. (Le module pyodbc requiert le package unixodbc sur UNIX, Linux et MacOS.) Vous configurez également un nom de source de données (DSN) ODBC pour vous authentifier et vous connecter à votre cluster ou à votre entrepôt SQL.

  1. Téléchargez et installez le pilote ODBC Databricks et configurez un DSN ODBC pour votre système d’exploitation.
  2. Pour Unix, Linux et macOS, installez le package unixodbc : à partir du terminal, utilisez Homebrew pour exécuter la commande brew install unixodbc. pour plus d’informations, consultez unixodbc sur le site web Homebrew.
  3. Installez le module pyodbc : à partir du terminal ou de l’invite de commandes, utilisez pip pour exécuter la commande pip install pyodbc. Pour plus d’informations, consultez pyodbc sur le site Web PyPI et Installation dans le wiki pyodbc.

Étape 2 : tester votre configuration

Au cours de cette étape, vous écrivez et exécutez du code Python pour utiliser votre cluster Azure Databricks ou entrepôt SQL Databricks pour interroger la table trips dans le schéma nyctrips du catalogue samples et afficher les résultats.

  1. Créez un fichier nommé pyodbc-demo.py avec le contenu suivant : Remplacez <dsn-name> par le nom de la table de la source de données ODBC créée précédemment, puis enregistrez le fichier et exécutez-le avec votre interpréteur Python.

    import pyodbc
    
    # Connect to the Databricks cluster by using the
    # Data Source Name (DSN) that you created earlier.
    conn = pyodbc.connect("DSN=<dsn-name>", autocommit=True)
    
    # Run a SQL query by using the preceding connection.
    cursor = conn.cursor()
    cursor.execute(f"SELECT * FROM samples.nyctaxi.trips")
    
    # Print the rows retrieved from the query.
    for row in cursor.fetchall():
      print(row)
    
  2. Pour accélérer l’exécution du code, démarrez le cluster qui correspond au paramètre HTTPPath dans votre DSN.

  3. Exécutez le fichier pyodbc-demo.py avec votre interpréteur Python. Des informations sur les lignes de la table sont affichées.

Étapes suivantes

  • Pour exécuter le code de test Python sur un autre cluster ou un entrepôt SQL, créez un autre DSN et remplacez <dsn-name> par le nom du DSN.
  • pour exécuter le code de test Python avec une autre requête de SQL, modifiez la chaîne de commande execute.

Utilisation d’une connexion sans DSN

En guise d’alternative à l’utilisation d’un nom DSN, vous pouvez spécifier les paramètres de connexion inlined. L’exemple suivant montre comment utiliser une chaîne de connexion sans DSN pour l’authentification par jeton d’accès personnel Azure Databricks. Cet exemple suppose que vous disposez des variables d’environnement suivantes :

Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.

import pyodbc
import os

conn = pyodbc.connect(
  "Driver=/Library/simba/spark/lib/libsparkodbc_sb64-universal.dylib;" +
  f"Host={os.getenv('DATABRICKS_HOST')};" +
  "Port=443;" +
  f"HTTPPath={os.getenv('DATABRICKS_HTTP_PATH')};" +
  "SSL=1;" +
  "ThriftTransport=2;" +
  "AuthMech=3;" +
  "UID=token;" +
  f"PWD={os.getenv('DATABRICKS_TOKEN')}",
  autocommit = True
)

# Run a SQL query by using the preceding connection.
cursor = conn.cursor()
cursor.execute("SELECT * FROM samples.nyctaxi.trips")

# Print the rows retrieved from the query.
for row in cursor.fetchall():
  print(row)

L’exemple suivant utilise l’authentification basée sur un navigateur OAuth utilisateur à machine (U2M) ou OAuth 2.0 au lieu d’un jeton d’accès personnel Azure Databricks. Cet exemple suppose que vous avez déjà défini les variables d’environnement DATABRICKS_SERVER_HOSTNAME et DATABRICKS_HTTP_PATH précédentes.

import pyodbc
import os

conn = pyodbc.connect(
  "Driver=/Library/simba/spark/lib/libsparkodbc_sb64-universal.dylib;" +
  f"Host={os.getenv('DATABRICKS_HOST')};" +
  "Port=443;" +
  f"HTTPPath={os.getenv('DATABRICKS_HTTP_PATH')};" +
  "SSL=1;" +
  "ThriftTransport=2;" +
  "AuthMech=11;" +
  "Auth_Flow=2;" +
  "PWD=1234567",
  autocommit = True
)

# Run a SQL query by using the preceding connection.
cursor = conn.cursor()
cursor.execute("SELECT * FROM samples.nyctaxi.trips")

# Print the rows retrieved from the query.
for row in cursor.fetchall():
  print(row)

L’exemple suivant utilise l’authentification des informations d’identification du client OAuth machine à machine (M2M) ou OAuth 2.0. Cet exemple suppose que vous avez déjà défini les variables d’environnement DATABRICKS_SERVER_HOSTNAME et DATABRICKS_HTTP_PATH précédentes, ainsi que les variables d’environnement suivantes :

  • Définissez ARM_CLIENT_ID sur la valeur ID d’application (client) du principal de service.
  • Définissez DATABRICKS_OAUTH_SECRET sur la valeur Secret OAuth du principal de service. (Les secrets Microsoft Entra ID ne sont pas pris en charge pour l’authentification des informations d’identification de client OAuth M2M ou OAuth 2.0 avec le pilote ODBC Databricks.)

Pour plus d’informations, consultez Authentification OAuth machine à machine (M2M).

import pyodbc
import os

conn = pyodbc.connect(
  "Driver=/Library/simba/spark/lib/libsparkodbc_sb64-universal.dylib;" +
  f"Host={os.getenv('DATABRICKS_HOST')};" +
  "Port=443;" +
  f"HTTPPath={os.getenv('DATABRICKS_HTTP_PATH')};" +
  "SSL=1;" +
  "ThriftTransport=2;" +
  "AuthMech=11;" +
  "Auth_Flow=1;" +
  f"Auth_Client_ID={os.getenv('ARM_CLIENT_ID')};" +
  f"Auth_Client_Secret={os.getenv('DATABRICKS_OAUTH_SECRET')}",
  autocommit = True
)

# Run a SQL query by using the preceding connection.
cursor = conn.cursor()
cursor.execute("SELECT * FROM samples.nyctaxi.trips")

# Print the rows retrieved from the query.
for row in cursor.fetchall():
  print(row)

Dépannage

Cette section traite des problèmes courants liés à l’utilisation de pyodbc avec Databricks.

Erreur de décodage Unicode

Problème : Vous recevez un message d'erreur semblable au suivant :

<class 'pyodbc.Error'> returned a result with an error set
Traceback (most recent call last):
File "/Users/user/.pyenv/versions/3.7.5/lib/python3.7/encodings/utf_16_le.py", line 16, in decode
return codecs.utf_16_le_decode(input, errors, True)
UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position 2112-2113: illegal UTF-16 surrogate

Cause: un problème existe dans la version 4.0.31 pyodbc ou inférieure qui pourrait manifester des symptômes lors de l’exécution de requêtes qui retournent des colonnes avec des noms longs ou un message d’erreur long. Le problème a été résolu par une version plus récente de pyodbc .

Solution: mettez à niveau votre installation de pyodbc vers la version 4.0.32 ou ultérieure.

Résolution générale des problèmes

Consultez les problèmes dans le référentiel mkleehammer/pyodbc sur GitHub.