PythonコネクタによるSnowflakeへの接続

このトピックでは、Pythonコネクタを使用してSnowflakeに接続するさまざまな方法について説明します。

SnowCD を使用したSnowflakeへのネットワーク接続の確認

ドライバーを設定したら、 SnowCD を使用して、Snowflakeへのネットワーク接続を評価およびトラブルシューティングできます。

初期構成プロセス中に SnowCD を使用して、オンデマンドでSnowflakeへのネットワーク接続を評価およびトラブルシューティングできます。

snowflake.connector モジュールのインポート

snowflake.connector モジュールをインポートするには、次のコマンドを実行します。

import snowflake.connector
Copy

環境変数、コマンドライン、構成ファイル、または別の適切なソースからログイン情報を取得できます。例:

PASSWORD = os.getenv('SNOWSQL_PWD')
WAREHOUSE = os.getenv('WAREHOUSE')
...
Copy

ACCOUNT パラメーターには、使用する アカウント識別子 を使用します。アカウント識別子には snowflakecomputing.com サフィックスが含まれて いない ことに注意してください。

詳細と例については、 account パラメーターの使用上の注意(connect メソッドの場合) をご参照ください。

注釈

使用可能なコネクタパラメーターの説明については、 snowflake.connector メソッド をご参照ください。

自分のAmazon S3バケットからデータをコピーする場合は、 AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY が必要です。

import os

AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
Copy

注釈

データがMicrosoft Azureコンテナーに保存されている場合は、 COPY ステートメントで認証情報を直接提供します。

接続情報を読み取った後、デフォルトの認証方式またはフェデレーション認証(有効な場合)を使用して接続します。

セッションパラメーターの設定

Pythonコネクタを使用する場合は、 QUERY_TAG のようなセッションパラメーターを複数の方法で設定できます。

  • 次のように、オプションの session_parameters という名前の接続パラメーターを渡すと、Snowflakeに接続するときにセッションレベルのパラメーターを設定できます。

    con = snowflake.connector.connect(
        user='XXXX',
        password='XXXX',
        account='XXXX',
        session_parameters={
            'QUERY_TAG': 'EndOfMonthFinancials',
        }
    )
    
    Copy

    connect() メソッドに渡される session_parameters ディクショナリには、1つ以上のセッションレベルのパラメーターを含めることができます。

  • 接続後に ALTER SESSION SET SQL ステートメントを実行して、セッションパラメーターを設定することもできます。

    con.cursor().execute("ALTER SESSION SET QUERY_TAG = 'EndOfMonthFinancials'")
    
    Copy

セッションパラメータの詳細については、一般的な パラメーター ページの個々のパラメーターの説明をご参照ください。

デフォルト認証方式を使用した接続

ログインパラメーターを使用してSnowflakeに接続します。

conn = snowflake.connector.connect(
    user=USER,
    password=PASSWORD,
    account=ACCOUNT,
    warehouse=WAREHOUSE,
    database=DATABASE,
    schema=SCHEMA
    )
Copy

これを他の情報で拡張する必要がある場合があります。

connections.toml ファイルを使用した接続

Pythonコネクタにより、 connections.toml 構成ファイルに接続定義を追加できます。接続定義とは、接続に関連するパラメーターのコレクションのことです。 toml ファイルフォーマットの詳細については、 TOML (Tom's Obvious Minimal Language) をご参照ください。Snowflake Pythonライブラリは現在、 TOML バージョン1.0.0をサポートしています。

Pythonコネクタは、 connections.toml ファイルを以下の場所で順に探します。

  • マシンに ~/.snowflake ディレクトリが存在する場合、Snowflake CLI は ~/.snowflake/connections.toml ファイルを使用します。 SNOWFLAKE_HOME 環境変数に場所を設定すると、デフォルトの ~/.snowflake ディレクトリを上書きすることができます。

  • そうでない場合、Snowflake CLI はオペレーティングシステムに応じて、次のいずれかの場所にある connections.toml ファイルを使用します。

    • Linux: ~/.config/snowflake/connections.toml。ただし、 XDG 変数で更新可

    • Windows: %USERPROFILE%\AppData\Local\snowflake\connections.toml

    • Mac: ~/Library/Application Support/snowflake/connections.toml

接続構成ファイルに認証情報を追加するには、

  1. テキストエディターで connections.toml ファイルを開いて編集します。たとえば、Linuxの vi エディターでファイルを開く場合:

    $ vi connections.toml
    
    Copy
  2. 新しいSnowflake接続定義を追加します。

    たとえば、アカウント myaccount、ユーザー johndoe、パスワード認証情報とデータベース情報を持つ myconnection というSnowflake接続を追加するには、構成ファイルに以下の行を追加します。

    [myconnection]
    account = "myaccount"
    user = "jdoe"
    password = "******"
    warehouse = "my-wh"
    database = "my_db"
    schema = "my_schema"
    
    Copy

    接続定義は、 Snowflake Pythonコネクタ で利用可能なものと同じ構成オプションをサポートします。

  3. オプション: 以下のように、さらに接続を追加します。

    [myconnection_test]
    account = "myaccount"
    user = "jdoe-test"
    password = "******"
    warehouse = "my-test_wh"
    database = "my_test_db"
    schema = "my_schema"
    
    Copy
  4. ファイルへの変更を保存します。

  5. Pythonコードでは、 snowflake.connector.connect に以下と類似した接続名を指定します。

    with snowflake.connector.connect(
          connection_name="myconnection",
    ) as conn:
    
    Copy

    以下のように、 connections.toml ファイルで接続に定義された値を上書きすることもできます。

    with snowflake.connector.connect(
          connection_name="myconnection",
          warehouse="test_xl_wh",
          database="testdb_2"
    ) as conn:
    
    Copy

デフォルト接続の設定

接続をデフォルトとして設定できるため、Snowflakeに接続するたびに snowflake.connector.connect() を呼び出して接続を指定する必要がありません。デフォルト接続を定義するには、優先順位の昇順に以下の方法があります。

  • default という名前の接続定義を作成します。

    1. connections.toml ファイルで接続定義を作成し、 default という名前を付けます。

      [default]
      account = "myaccount"
      user = "jdoe-test"
      password = "******"
      warehouse = "my-test_wh"
      database = "my_test_db"
      schema = "my_schema"
      
      Copy
    2. ファイルを保存します。

  • connections.toml ファイルと同じディレクトリにあるSnowflake config.toml ファイルで、名前付き接続をデフォルト接続として指定します。

    1. 編集のために config.toml ファイルを開きます。そして、

    2. default_connection_name パラメーターを以下のように設定します。

      default_connection_name = "myaccount"
      
      Copy
    3. ファイルを保存します。

  • SNOWFLAKE_DEFAULT_CONNECTION_NAME 環境変数を設定します。

    テスト接続の試行など、通常のデフォルト接続を変更することなく、一時的にデフォルト接続を上書きすることが必要になる場合があります。以下のように、 SNOWFLAKE_DEFAULT_CONNECTION_NAME 環境変数を設定すると、 connections.tomlconfig.toml ファイルで指定されたデフォルトの接続を上書きできます。

    SNOWFLAKE_DEFAULT_CONNECTION_NAME = myconnection_test
    
    Copy

デフォルト接続を使用するには、以下のようなPythonコードを実行します。

with snowflake.connector.connect() as conn:
    with conn.cursor() as cur:
        print(cur.execute("SELECT 1;").fetchall())
Copy

注釈

デフォルト接続に依存することを選択した場合は、 usernamedatabaseschema などの接続パラメーターを上書きすることはできません。

認証でのシングルサインオン(SSO)の使用

シングルサインオン(SSO)を使用するようにSnowflakeを構成 している場合、認証に SSO を使用するようにクライアントアプリケーションを構成できます。詳細については Snowflakeに接続するクライアントアプリケーションでの SSO の使用 をご参照ください。

多要素認証(MFA)の使用

Snowflakeは、 MFA トークンキャッシングと SSO の組み合わせを含む、 MFA トークンのキャッシングをサポートしています。

詳細については、 MFA トークンキャッシングを使用して認証中のプロンプトの数を最小限に抑える --- オプション をご参照ください。

キーペア認証とキーペアローテーションの使用

Pythonコネクタは、キーペア認証とキーローテーションをサポートしています。

キーペア認証とキーローテーションを構成する方法の詳細については、 キーペア認証とキーペアローテーション をご参照ください。

  1. キーペア認証の構成が完了したら、 connect 関数の private_key パラメーターを秘密キーファイルへのパスに設定します。

  2. 以下のサンプルコードを変更して実行します。コードは秘密キーファイルを復号化し、Snowflakeドライバーに渡して接続を作成します。

サンプルコード

import snowflake.connector
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric import dsa
from cryptography.hazmat.primitives import serialization
with open("<path>/rsa_key.p8", "rb") as key:
    p_key= serialization.load_pem_private_key(
        key.read(),
        password=os.environ['PRIVATE_KEY_PASSPHRASE'].encode(),
        backend=default_backend()
    )

pkb = p_key.private_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption())

ctx = snowflake.connector.connect(
    user='<user>',
    account='<account_identifier>',
    private_key=pkb,
    warehouse=WAREHOUSE,
    database=DATABASE,
    schema=SCHEMA
    )

cs = ctx.cursor()
Copy

プロキシサーバーの使用

プロキシサーバーを使用するには、次の環境変数を構成します。

  • HTTP_PROXY

  • HTTPS_PROXY

  • NO_PROXY

例:

Linuxまたは macOS
export HTTP_PROXY='http://username:password@proxyserver.company.com:80'
export HTTPS_PROXY='http://username:password@proxyserver.company.com:80'
Copy
Windows
set HTTP_PROXY=http://username:password@proxyserver.company.com:80
set HTTPS_PROXY=http://username:password@proxyserver.company.com:80
Copy

ちなみに

Snowflakeのセキュリティモデルは、Secure Sockets Layer(SSL)プロキシを許可しません( HTTPS 証明書を使用)。プロキシサーバーは、公的に利用可能な認証機関(CA)を使用する必要があり、侵害されたプロキシを介した MITM (Man In The Middle)攻撃などの潜在的なセキュリティリスクを低減します。

SSL プロキシを使用する 必要 がある場合は、通信中に証明書が変更されないように、サーバーポリシーを更新してSnowflake証明書を渡すことを強くお勧めします。

オプションで NO_PROXY を使用して、特定の通信のプロキシをバイパスできます。たとえば、Amazon S3へのアクセスは、 NO_PROXY=".amazonaws.com" を指定してプロキシサーバーをバイパスできます。

NO_PROXY はワイルドカードをサポートしていません。指定する各値は、次のいずれかである必要があります。

  • ホスト名の末尾(または完全なホスト名)。例:

    • .amazonaws.com

    • myorganization-myaccount.snowflakecomputing.com

  • IP アドレス。例:

    • 192.196.1.15

複数の値を指定する場合、値はコンマで区切る必要があります。次に例を示します。

localhost,.my_company.com,.snowflakecomputing.com,192.168.1.15,192.168.1.16
Copy

OAuth との接続

OAuthを使用して接続するには、接続文字列に oauth に設定された authenticator パラメーターと oauth_access_token に設定された token パラメーターを含める必要があります。詳細については、 クライアント、ドライバー、およびコネクタ をご参照ください。

ctx = snowflake.connector.connect(
    user="<username>",
    host="<hostname>",
    account="<account_identifier>",
    authenticator="oauth",
    token="<oauth_access_token>",
    warehouse="test_warehouse",
    database="test_db",
    schema="test_schema"
)
Copy

接続タイムアウトの管理

snowflake.connector.connect を呼び出すと、ログインリクエストが送信されます。ログインリクエストが失敗した場合、コネクタで接続リクエストを再送することができます。以下のパラメーターは、コネクタがリクエストの再試行を停止するまでの制限時間を設定します。

  • login_timeout: 接続リクエストを再送し続ける時間を秒単位で指定します。その時間内で接続が失敗した場合、コネクタはログインリクエストを再試行し続けるのではなく、現在の試行を完了した後にタイムアウトエラーで失敗します。タイムアウトを過ぎると、それ以上の再試行はできなくなります。しかし、現在進行中の試行は自然に終了します。

  • network_timeout: cursor.execute からのクエリリクエストなど、他のリクエストに対してネットワークの問題が解決するまでの待ち時間を指定します。現在の試行が失敗して network_timeout 秒が経過し、タイムアウトが発生して当該リクエストが再試行されない場合。 network_timeout 秒経過後、現在の試行が終了する(自然に失敗する)ことは引き続き許可され、その後にタイムアウトが発生します。

  • socket_timeout: ソケットレベルでの接続とリクエストのタイムアウトを指定します。

次の例では、 SNOWFLAKE_JWT 認証コードの socket_timeout を上書きしています。

# this request itself stops retrying after 60 seconds as it is a login request
conn = snowflake.connector.connect(
login_timeout=60,
network_timeout=30,
socket_timeout=10
)

# this request stops retrying after 30 seconds
conn.cursor.execute("SELECT * FROM table")
Copy

次の例は、 socket_timeout を大きな値に設定した場合の効果を示しています。

# even though login_timeout is 1, connect will take up to n*300 seconds before failing
# (n depends on possible socket addresses)
# this issue arises because socket operations cannot be cancelled once started
conn = snowflake.connector.connect(
login_timeout=1,
socket_timeout=300
)
Copy

次の例は、 SNOWFLAKE_JWT 認証コードのソケットタイムアウトを上書きする方法を示しています。

# socket timeout for login request overriden by env variable JWT_CNXN_WAIT_TIME
conn = snowflake.connector.connect(
authenticator="SNOWFLAKE_JWT",
socket_timeout=300
)

# socket timeout for this request is still 300 seconds
conn.cursor.execute("SELECT * FROM table")
Copy

MAX_CON_RETRY_ATTEMPTS 環境変数は、ログインリクエストの最大再試行回数を制限することに注意してください。リクエストがタイムアウトしていないが、最大再試行回数に達している場合、リクエストは即座に失敗します。デフォルト値は1で、コネクタは1回だけ再試行を行います。

再試行のための接続バックオフポリシーの管理

状況によっては、コネクタがタイムアウトによる失敗したリクエストを再試行する割合や頻度を変えたい場合があります。たとえば、非常に多くの試行が同時に発生することに気づいたら、再試行のバックオフポリ シーを定義することで、それらのリクエストを分散させることができます。バックオフポリシーでは、再試行までの待ち時間を指定します。

Python用Snowflakeコネクタは、Pythonジェネレーター関数を指定する backoff_policy 接続パラメーターでバックオフポリシーを実装します。ジェネレーター関数では、次の再試行リクエストを送信するまでの待ち時間(バックオフ)を指定できます。

Snowflakeには、希望するパラメーターを持つ定義済みジェネレーター関数を作成するため、次のヘルパーが用意されています。自分で作成したくない場合は、以下を使用することができます。

  • linear_backoff、これは各反復ごとにバックオフ時間を一定に増加させます。

  • exponential_backoff、これは各反復ごとにバックオフ時間を定数倍します。

  • mixed_backoff、これはバックオフ時間を exponential_backoff で増分するか、そのままにするかを各反復でランダムに選択します。

これらの定義済みジェネレーター関数は、次のパラメーターを使用して動作を指定します。

  • base: 秒単位の初期バックオフ時間(デフォルト = 1)。

  • factor: バックオフ時間を増分する係数。効果は実装によって異なります(デフォルト = 2)。 linear_backup は値を加算し、 exponential_backup は値を乗算します。

  • cap: 秒単位の最大バックオフ時間(デフォルト = 16)。

  • enable_jitter: 計算された持続時間のジッターを有効化するかどうか(デフォルト = True)。指数関数的バックオフにおけるジッターの詳細については、 AWS 指数関数的バックオフとジッター の記事をご参照ください。

たとえば、次のように、 exponential_backoff ポリシーをデフォルト値またはカスタム値で使用できます。

from snowflake.connector.backoff_policies import exponential_backoff

# correct, no required arguments
snowflake.connector.connect(
backoff_policy=exponential_backoff()
)

# correct, parameters are customizeable
snowflake.connector.connect(
backoff_policy=exponential_backoff(
    factor=5,
    base=10,
    cap=60,
    enable_jitter=False
  )
)
Copy

また、 my_backoff_policy ジェネレーター関数を定義する次の例のように、独自のバックオフポリシージェネレーター関数を作成することもできます。

def my_backoff_policy() -> int:
  while True:
    # yield the desired backoff duration
Copy

次に、 backoff_policy 接続パラメーターにジェネレーター関数の名前を次のように設定します。

snowflake.connector.connect(
  backoff_policy=constant_backoff
)
Copy

OCSP

ドライバーが接続すると、Snowflakeは証明書を送信して、Snowflakeを偽装しているホストではなく、Snowflakeへの接続であることを確認します。ドライバーはその証明書を OCSP (オンライン証明書状態プロトコル)サーバーに送信し、証明書が失効していないことを確認します。

ドライバーが証明書を確認するために OCSP サーバーに到達できない場合、ドライバーは "fail open" or "fail closed" できます。

フェールオープンまたはフェールクローズモードの選択

1.8.0より前のバージョンのPython用Snowflakeコネクタは、デフォルトでフェールクローズモードに設定されています。バージョン1.8.0以降はデフォルトでフェールオープンになります。connect()メソッドを呼び出すときにオプションの接続パラメーター ocsp_fail_open を設定することにより、デフォルトの動作を上書きできます。例:

con = snowflake.connector.connect(
    account=<account_identifier>,
    user=<user>,
    ...,
    ocsp_fail_open=False,
    ...);
Copy

OCSP コネクタまたはドライバーバージョンの確認

ドライバーまたはコネクタのバージョンとその構成により、 OCSP の動作が決まります。ドライバーまたはコネクタのバージョン、それらの構成、および OCSP の動作の詳細については、 OCSP 設定 をご参照ください。

OCSP 応答のキャッシュ

すべての通信が安全であることを確認するために、Python用Snowflakeコネクタは HTTPS プロトコルを使用してSnowflakeおよび他のすべてのサービスに接続します(例:データファイルのステージング用のAmazon S3およびフェデレーション認証用のOkta)。通常の HTTPS プロトコルに加えて、コネクタは OCSP(オンライン証明書状態プロトコル)を介して各接続の TLS/SSL 証明書失効ステータスもチェックし、証明書が失効した場合や、OCSP ステータスが信頼できない場合は、接続を中止します。

各Snowflake接続は OCSP サーバーとの最大3つのラウンドトリップをトリガーするため、 OCSP 応答の複数レベルのキャッシュを導入して、接続に追加されるネットワークオーバーヘッドを削減しました。

  • プロセスの存続期間中保持されるメモリキャッシュ。

  • ファイルキャッシュ。キャッシュディレクトリ(例: ~/.cache/snowflake)がパージされるまで保持されます。

  • OCSP 応答サーバーキャッシュ。

キャッシュは、 OCSP サーバーの可用性の問題にも対処します(つまり、実際の OCSP サーバーがダウンした場合)。キャッシュが有効である限り、コネクタは証明書失効ステータスを検証できます。

キャッシュレイヤーに OCSP 応答が含まれていない場合、クライアントは CAの OCSP サーバーから検証ステータスを直接フェッチしようとします。

OCSP 応答ファイルキャッシュの場所の変更

デフォルトでは、ファイルキャッシュは次の場所で有効になっているため、追加の構成タスクは必要ありません。

Linux

~/.cache/snowflake/ocsp_response_cache.json

macOS

~/Library/Caches/Snowflake/ocsp_response_cache.json

Windows

%USERPROFILE%\AppData\Local\Snowflake\Caches\ocsp_response_cache.json

ただし、 OCSP 応答キャッシュファイルに別の場所やファイル名を指定する場合、 connect メソッドは URI 形式の OCSP キャッシュファイルのパスと名前を指定する、 ocsp_response_cache_filename パラメーターを受け入れます。

OCSP 応答キャッシュサーバー

注釈

OCSP 応答キャッシュサーバーは現在、Python用Snowflakeコネクタ1.6.0以降でサポートされています。

OCSP キャッシュのメモリとファイルの種類は、Snowflakeが提供するクライアントの1つを永続的なホストで使用して、Snowflakeに接続されたアプリケーションで良好に機能します。ただし、 AWS LambdaやDockerなどの動的にプロビジョニングされた環境では機能しません。

この状況に対処するために、Snowflakeは3番目のキャッシュレベルである OCSP 応答キャッシュサーバーを提供します。OCSP 応答キャッシュサーバーは、 CAの OCSP サーバーから1時間ごとに OCSP 応答をフェッチし、24時間保存します。クライアントは、このサーバーキャッシュから特定のSnowflake証明書の検証ステータスをリクエストできます。

重要

サーバーポリシーでほとんどまたはすべての外部 IP アドレスおよびウェブサイトへのアクセスが拒否された場合、通常のサービス操作を許可するには、キャッシュサーバーアドレスを 必ず 許可する必要があります。キャッシュサーバー URL は ocsp*.snowflakecomputing.com:80 です。

何らかの理由でキャッシュサーバーを無効化する必要がある場合は、 SF_OCSP_RESPONSE_CACHE_SERVER_ENABLED 環境変数を false に設定します。値は大文字と小文字が区別され、小文字にする必要があることに注意してください。