Python と pyodbc を Azure Databricks に接続する
ローカルの Python コードから ODBC を介して、Azure Databricks クラスターまたは SQL ウェアハウスのデータに接続できます。 これを行うには、オープンソースの Python コード モジュール pyodbc
を使用します。
下記の指示に従って、pyodbc
をインストールして構成し、使用します。
pyodbc
の詳細については、pyodbc Wiki を参照してください。
注意
Databricks には、pyodbc
の代替として、Databricks SQL Connector for Python が用意されています。 Databricks SQL Connector for Python は、設定と使用がより簡単で、pyodbc
よりも堅牢な一連のコーディング構造を備えています。 ただし、10 MB を超えるクエリ結果をフェッチするときのパフォーマンスは、pyodbc
の方が高い場合があります。
これらの手順は、Databricks ODBC ドライバー 2.7.5、pyodbc 5.0.1、unixODBC 2.3.12 でテストされました。
要件
- 以下のいずれかを実行しているローカルの開発マシン。
- macOS
- Windows
.rpm
または.deb
ファイルをサポートしている Unix または Linux ディストリビューション
- pip。
- Unix、Linux、または macOS の場合は Homebrew。
- Azure Databricks クラスター、Databricks SQL ウェアハウス、またはその両方。 詳細については、「構成リファレンスおよび SQL ウェアハウスへの接続を参照してください。
手順 1: ソフトウェアのダウンロード、インストール、構成
この手順では、Databricks ODBC ドライバー、unixodbc
パッケージ、pyodbc
モジュールをダウンロードしてインストールします。 (pyodbc
モジュールを使用するには、Unix、Linux、macOS 上に unixodbc
パッケージが必要です。)また、クラスターまたは SQL ウェアハウスを認証して接続するための ODBC データ ソース名 (DSN) も構成します。
- Databricks ODBC ドライバーをダウンロードしてインストールし、オペレーティング システムに合わせて ODBC DSN を構成します。
- Unix、Linux、macOS の場合は、
unixodbc
パッケージをインストールします。ターミナルから Homebrew を使用してコマンドbrew install unixodbc
を実行します。 詳細については、Homebrew Web サイトの「unixodbc」を参照してください。 pyodbc
モジュールをインストールします。ターミナルまたはコマンド プロンプトから、pip
を使ってコマンドpip install pyodbc
を実行します。 詳細については、PyPI Web サイトの「pyodbc」と、pyodbc Wiki の「Install」を参照してください。
手順 2: 構成をテストする
この手順では、Azure Databricks クラスターまたは Databricks SQL ウェアハウスを使って、samples
カタログの nyctrips
スキーマ内の trips
テーブルに対してクエリを実行し、結果を表示する Python コードを作成して実行します。
次の内容を含む
pyodbc-demo.py
という名前のファイルを作成します。<dsn-name>
を前に作成した ODBC DSN の名前に置き換え、ファイルを保存してから、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)
コードの実行を高速化するため、DSN 内の
HTTPPath
設定に対応するクラスターを起動します。Python インタープリターで
pyodbc-demo.py
ファイルを実行します。 テーブルの行に関する情報が表示されます。
次のステップ
- 別のクラスターまたは SQL ウェアハウスに対して Python テスト コードを実行するには、別の DSN を作成し、
<dsn-name>
を DSN の名前に変更します。 - 異なる SQL クエリを使用して Python テスト コードを実行するには、
execute
コマンド文字列を変更します。
DSN を使用しない接続の使用
DSN 名を使用する代わりに、接続設定をインラインで指定することもできます。 次の例は、Azure Databricks の個人用アクセス トークン認証に DSN を使用しない接続文字列を使用する方法を示しています。 この記事では、次の環境変数があることを前提としています。
DATABRICKS_SERVER_HOSTNAME
をワークスペース インスタンス名 (たとえばadb-1234567890123456.7.azuredatabricks.net
) に設定します。DATABRICKS_HTTP_PATH
を、ワークスペース内のターゲット クラスターまたは SQL ウェアハウスの HTTP Path 値に設定します。 HTTP パス値を取得するには、「Azure Databricks コンピューティング リソースの接続の詳細を取得する」を参照してください。DATABRICKS_TOKEN
をターゲット ユーザーの Azure Databricks 個人用アクセス トークンに設定します。 個人用アクセス トークンを作成するには、「ワークスペース ユーザーの Azure Databricks 個人用アクセス トークン」を参照してください。
環境変数を設定するには、オペレーティング システムのドキュメントを参照してください。
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)
次の例では、Azure Databricks の個人用アクセス トークンの代わりに、OAuth ユーザーツーマシン (U2M) 認証または OAuth 2.0 ブラウザー ベースの認証を使用しています。 この例では、前述の環境変数 DATABRICKS_SERVER_HOSTNAME
と DATABRICKS_HTTP_PATH
が既に設定されていることを前提としています。
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)
次の例では、OAuth マシン間 (M2M) 認証または OAuth 2.0 クライアント資格情報認証を使用しています。 この例では、前述の環境変数 DATABRICKS_SERVER_HOSTNAME
と DATABRICKS_HTTP_PATH
、および次の環境変数が既に設定されていることを前提としています。
- サービス プリンシパルの [アプリケーション (クライアント) ID] 値に
ARM_CLIENT_ID
を設定します。 - サービス プリンシパルの OAuth シークレットの [シークレット] 値に
DATABRICKS_OAUTH_SECRET
を設定します。 (Microsoft Entra ID シークレットは、Databricks ODBC ドライバーを使用した OAuth M2M 認証または OAuth 2.0 クライアント資格情報認証ではサポートされていません。)
詳細については、「OAuth マシン間 (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)
トラブルシューティング
このセクションでは、Databricks で pyodbc
を使用する場合の一般的な問題を扱います。
Unicode のデコード エラー
問題: 次のようなエラー メッセージが表示されます。
<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
原因: pyodbc
バージョン 4.0.31 以下には、長い名前の列や長いエラー メッセージを返すクエリを実行するとこのような現象が発生する可能性のある問題が存在します。 この問題は、新しいバージョンの pyodbc
によって修正されています。
解決策: お使いの pyodbc
のインストールをバージョン 4.0.32 以上にアップグレードします。
一般的なトラブルシューティング
GitHub の mkleehammer/pyodbc リポジトリで「イシュー」を参照してください。