Node.jsドライバーの使用

ドライバーを使用するための一般的なワークフローは次のとおりです。

  1. Snowflakeとの接続を確立します。

  2. クエリや DDL/DML コマンドなどのステートメントを実行します。

  3. 結果を利用します。

  4. 接続を終了します。

重要

ドライバーは現在、 PUT または GET コマンドをサポートしていないため、データのロード/アンロード用のファイルのアップロードまたはダウンロードには使用できません。代わりに SnowSQL (CLI クライアント) または JDBC ドライバー を使用してください。

このトピックの内容:

接続の確立

Snowflakeに対してステートメントを実行するには、最初に接続を確立する必要があります。

  1. snowflake.createConnection を呼び出して新しい Connection オブジェクトを作成し、 接続オプション を指定する JavaScript オブジェクトを渡します。

  2. Connection オブジェクトを使用して connect メソッドを呼び出し、接続を確立します。

    注釈

    authenticator オプションを EXTERNALBROWSERブラウザーベースの SSO を使用するため)、または https://<Oktaアカウント名>.okta.comOktaを介したネイティブ SSO を使用するため)に設定した場合、 connect メソッドではなく connectAsync メソッドを呼び出します。

    接続エラーを処理するには、次の署名を持つコールバック関数を渡します。

    function(err, conn)
    

    条件:

    • err は、 JavaScript Error オブジェクトです。

    • conn は、現在の Connection オブジェクトです。

    接続中にエラーが発生した場合、 connect メソッドは Error オブジェクトをコールバック関数に渡します。コールバック関数でこのオブジェクトを使用すると、エラーの詳細を取得できます。現在の Connection オブジェクトに関する情報が必要な場合は、コールバック関数に渡された conn 引数を使用できます。

次の例では、接続を確立し、認証にパスワードを使用します。他の認証方法を使用するには、 認証オプション をご参照ください。

// Load the Snowflake Node.js driver.
var snowflake = require('snowflake-sdk');
// Create a Connection object that we can use later to connect.
var connection = snowflake.createConnection( {
    account: account,
    username: user,
    password: password
    }
    );
// Try to connect to Snowflake, and check whether the connection was successful.
connection.connect( 
    function(err, conn) {
        if (err) {
            console.error('Unable to connect: ' + err.message);
            } 
        else {
            console.log('Successfully connected to Snowflake.');
            // Optional: store the connection ID.
            connection_ID = conn.getId();
            }
        }
    );

接続を作成するときに、以下のセクションで説明するオプションを設定できます。

接続オプションの設定

新しい Connection オブジェクトを構築するときは、接続のオプション(アカウント、ユーザー名など)を指定する JavaScript オブジェクトで渡します。次のセクションでは、設定できるオプションについて説明します。オプションを設定するには、 JavaScript オブジェクトのプロパティ名としてオプション名を指定します。

必要な接続オプション

account

アカウントのフルネーム(Snowflakeが提供)。完全なアカウント名には、アカウントがホストされている 地域 および クラウドプラットフォーム を識別する 追加 のセグメントが含まれている場合があります。

リージョン別のアカウント名の例

アカウントロケーターが xy12345 の場合:

クラウドプラットフォーム / . リージョン

アカウントロケーター . (必要に応じて追加のセグメントを含む)

Amazon Web Services(AWS)

US 西部(オレゴン)

xy12345

US 東部(オハイオ)

xy12345.us-east-2.aws

US 東部(バージニア北部)

xy12345.us-east-1

US 東部(商業組織、バージニア政府北部)

xy12345.us-east-1-gov.aws

カナダ(中部)

xy12345.ca-central-1.aws

EU (アイルランド)

xy12345.eu-west-1

ヨーロッパ(ロンドン)

xy12345.eu-west-2.aws

EU (フランクフルト)

xy12345.eu-central-1

アジア太平洋(東京)

xy12345.ap-northeast-1.aws

アジア太平洋(ムンバイ)

xy12345.ap-south-1.aws

アジア太平洋(シンガポール)

xy12345.ap-southeast-1

アジア太平洋(シドニー)

xy12345.ap-southeast-2

Google Cloud Platform(GCP)

US 中央部1(アイオワ)

xy12345.us-central1.gcp

ヨーロッパ西部2(ロンドン)

xy12345.europe-west2.gcp

ヨーロッパ西部4(オランダ)

xy12345.europe-west4.gcp

Microsoft Azure

西 US 2(ワシントン)

xy12345.west-us-2.azure

東 US 2(バージニア)

xy12345.east-us-2.azure

US 政府バージニア

xy12345.us-gov-virginia.azure

カナダ中央部(トロント)

xy12345.canada-central.azure

西ヨーロッパ(オランダ)

xy12345.west-europe.azure

スイス北部(チューリッヒ)

xy12345.switzerland-north.azure

東南アジア(シンガポール)

xy12345.southeast-asia.azure

オーストラリア東部(ニューサウスウェールズ)

xy12345.australia-east.azure

重要

次のいずれかの条件に該当する場合、アカウントロケーターは、上記の例の構造とは異なります。

  • Snowflake Editionが VPS の場合、アカウントロケーターの詳細については Snowflakeサポート にお問い合わせください。

  • アカウントで AWS PrivateLink またはAzure Private Linkが有効になっており、プライベート接続を使用してSnowflakeに接続する場合は、 SYSTEM$GET_PRIVATELINK_CONFIG 関数を実行して、使用するプライベート接続 URL を決定します。

    プライベート接続の詳細については、以下をご参照ください。

username

SnowflakeユーザーまたはIDプロバイダーのログイン名(例: Oktaのログイン名)。

region --- 廃止

アカウントが存在する リージョン の ID。

必要に応じてリージョン情報が完全なアカウント名の一部として含まれるため、このオプションは使用されなくなりました。ここでは、下位互換性のためにのみ文書化されています。

加えて、 サーバーに対する認証のオプション を指定する必要があります。

認証オプション

authenticator

ユーザーログイン認証情報の検証に使用する認証方式を指定します。これは、次のいずれかの値に設定できます。

説明

SNOWFLAKE

内部Snowflake認証方式を使用します。 password オプションも設定する必要があります。

EXTERNALBROWSER

自分のウェブブラウザーを使用 して、Okta、 ADFS、またはアカウントに定義されている他の SAML 2.0準拠の識別プロバイダー(IdP)で認証します。

https://<Oktaアカウント名>.okta.com

Oktaを介したネイティブ SSO の使用

OAUTH

認証には OAuth を使用します。また、 token オプションを OAuth トークンに設定する必要があります(以下を参照)。

SNOWFLAKE_JWT

キーペア認証を使用します。 キーペア認証およびキーペアローテーションの使用 をご参照ください。

デフォルト値は SNOWFLAKE です。

認証の詳細については、 フェデレーション認証の管理/使用 および OAuth のクライアント、ドライバー、およびコネクター をご参照ください。

password

ユーザーのパスワード。 authenticator オプションを SNOWFLAKE を設定するか、 Oktaアカウント用のOkta URL エンドポイント (例: https://<Oktaアカウント名>.okta.com)を設定した場合や、 authenticator オプションを未設定にした場合は、このオプションを設定します。

token

認証に使用する OAuth トークンを指定します。 authenticator オプションを OAUTH に設定する場合は、このオプションを設定します。

privateKey

キーペア認証の秘密キー( PEM 形式内)を指定します。詳細については、 キーペア認証およびキーペアローテーションの使用 をご参照ください。

privateKeyPath

秘密キーファイル(例: rsa_key.p8)に対するローカルパスを指定します。詳細については、 キーペア認証およびキーペアローテーションの使用 をご参照ください。

privateKeyPass

ファイルが暗号化されている場合に、秘密キーファイルを復号化するためのパスコードを指定します。詳細については、 キーペア認証およびキーペアローテーションの使用 をご参照ください。

追加の接続オプション

database

接続後にセッションに使用するデフォルトのデータベース。

schema

接続後にセッションに使用するデフォルトのスキーマ。

warehouse

接続後にセッションに使用するデフォルトの仮想ウェアハウス。クエリの実行、データのロードなどに使用されます。

role

接続後にセッションに使用するデフォルトのセキュリティロール。

clientSessionKeepAlive

デフォルトでは、クライアント接続は通常、最新のクエリが実行されてから約3~4時間後にタイムアウトします。

clientSessionKeepAlive オプションが true に設定されている場合、クエリが実行されなくても、サーバーへのクライアントの接続は無期限に維持されます。

このオプションのデフォルト設定はfalseです。

このオプションを true に設定する場合は、プログラムの終了時にプログラムがサーバーから明示的に切断されていることを確認します。切断せずに終了しないでください。

clientSessionKeepAliveHeartbeatFrequency

clientSessionKeepAlive がtrueの場合にのみ適用)

このオプションは、ハートビートメッセージの頻度(秒単位の間隔)を設定します。

接続ハートビートメッセージは、クエリを置き換え、接続のタイムアウトカウントダウンを再開するものと大まかに考えることができます。つまり、少なくとも4時間の非アクティブ後に接続がタイムアウトすると、ハートビートはタイマーをリセットし、最新のハートビート(またはクエリ)の少なくとも4時間後までタイムアウトが発生しないようにします。

デフォルト値は3600秒(1時間)です。有効な値の範囲は900~3600です。通常、タイムアウトは少なくとも4時間後に発生するため、通常、接続を維持するには1時間ごとのハートビートで十分です。3600秒未満のハートビート間隔が必要になることはほとんどありません。

一部の接続オプションは、指定されたデータベースオブジェクト(データベース、スキーマ、ウェアハウス、またはロール)がシステムに既に存在することを前提としています。指定したオブジェクトが存在しない場合、接続中にデフォルトは設定されません。

接続後、オプションの接続オプションはすべて USE <object> コマンドで設定または上書きすることもできます。

Snowflakeに対する認証

Snowflakeに対する認証には、次のいずれかのオプションを使用できます。

ウェブブラウザーを介したシングルサインオン(SSO)の使用

シングルサインオン(SSO)を使用するようにSnowflakeを構成 している場合は、認証にブラウザーベースの SSO を使用するようにクライアントアプリケーションを構成できます。

アプリケーションコード内で、

  1. authenticator オプションを EXTERNALBROWSER に設定します。

  2. 接続を確立するには、 connect メソッドではなく connectAsync メソッドを呼び出します。

例:

// Use a browser to authenticate via SSO.
var connection = snowflake.createConnection({
  ...,
  authenticator: "EXTERNALBROWSER"
});
// Establish a connection. Use connectAsync, rather than connect.
connection.connectAsync(
  function (err, conn)
  {
    ... // Handle any errors.
  }
).then(() =>
{
  // Execute SQL statements.
  var statement = connection.execute({...});
});

認証にブラウザーベースの SSO を使用する方法の詳細については、 ブラウザーベース SSO をご参照ください。

Oktaを介したネイティブ SSO の使用

Oktaを介して シングルサインオン(SSO)を使用するようにSnowflakeを構成 している場合は、Oktaを介してネイティブ SSO 認証を使用するようにクライアントアプリケーションを構成できます。

アプリケーションコード内で、

  1. 次のオプションを設定します。

    • authenticator オプションをOktaアカウントのOkta URL エンドポイントに設定します(例: https://<Oktaアカウント名>.okta.com)。

    • username および password オプションをIDプロバイダー(IdP)のユーザー名とパスワードに設定します。

  2. 接続を確立するには、 connect メソッドではなく connectAsync メソッドを呼び出します。

例:

// Use native SSO authentication through Okta.
var connection = snowflake.createConnection({
  ...,
  username: '<user_name_for_okta>',
  password: '<password_for_okta>',
  authenticator: "https://myaccount.okta.com"
});

// Establish a connection.
connection.connectAsync(
  function (err, conn)
  {
    ... // Handle any errors.
  }
);

// Execute SQL statements.
var statement = connection.execute({...});

Oktaを介したネイティブ SSO 認証の使用の詳細については、 ネイティブ SSO --- Oktaのみ をご参照ください。

キーペア認証およびキーペアローテーションの使用

ドライバーは、キーペア認証とキーローテーションをサポートします。これを使用するには、

  1. キーペア認証およびキーペアローテーション で説明されているように、キーペア認証を構成します。

  2. アプリケーションコード内で、

    1. authenticator オプションを SNOWFLAKE_JWT に設定します。

    2. 秘密キーを使用して、次のいずれかの方法で認証します。

      • privateKey オプションを秘密キーに設定します。

      • privateKeyPath オプションを秘密キーファイルへのパスに設定します。

        ファイルが暗号化されている場合は、 privateKeyPass オプションをパスフレーズに設定して秘密キーを復号化する必要もあります。

次の例では、ファイルから秘密キーをロードし、 privateKey オプションを秘密キーに設定します。

// Read the private key file from the filesystem.
var crypto = require('crypto');
var fs = require('fs');
var privateKeyFile = fs.readFileSync('<path_to_private_key_file>/rsa_key.p8');

// Get the private key from the file as an object.
const privateKeyObject = crypto.createPrivateKey({
  key: privateKeyFile,
  format: 'pem',
  passphrase: 'passphrase'
});

// Extract the private key from the object as a PEM-encoded string.
var privateKey = privateKeyObject.export({
  format: 'pem',
  type: 'pkcs8'
});

// Use the private key for authentication.
var connection = snowflake.createConnection({
  ...
  authenticator: "SNOWFLAKE_JWT",
  privateKey: privateKey
});

// Establish a connection.
connection.connect(
  function (err, conn)
  {
    ... // Handle any errors.
  }
);

// Execute SQL statements.
var statement = connection.execute({...});

次の例では、 privateKeyPath オプションを暗号化された秘密キーファイルに設定し、 privateKeyPass オプションを秘密キーの復号化に使用されるパスフレーズに設定します。

// Use an encrypted private key file for authentication.
// Specify the passphrase for decrypting the key.
var connection = snowflake.createConnection({
  ...
  authenticator: "SNOWFLAKE_JWT",
  privateKeyFile: "<path-to-privatekey>/privatekey.p8",
  privateKeyPass: '<passphrase_to_decrypt_the_private_key>'
});

// Establish a connection.
connection.connect(
  function (err, conn)
  {
    ... // Handle any errors.
  }
);

// Execute SQL statements.
var statement = connection.execute({...});

OAuth の使用

OAuth を使用して接続するには、 authenticator オプションを OAUTH に設定し、 token オプションを OAuth アクセストークンに設定します。例:

// Use OAuth for authentication.
var connection = snowflake.createConnection({
  ...
  authenticator: "OAUTH",
  token: "<your_oauth_token>"
});

// Establish a connection.
connection.connect(
  function (err, conn)
  {
    ... // Handle any errors.
  }
);

// Execute SQL statements.
var statement = connection.execute({...});

詳細については、 OAuth のクライアント、ドライバー、およびコネクター をご参照ください。

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

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

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

OCSP (オンライン証明書状態プロトコル)

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

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

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

1.2.0より前のバージョンのNode.jsドライバーは、デフォルトでフェールクローズになります。バージョン1.2.0以降はデフォルトでフェールオープンになります。 snowflake.createConnection() メソッドを呼び出す前に ocspFailOpen グローバルパラメーターを設定することにより、デフォルトの動作を上書きできます。パラメーターは、trueまたはfalseに設定できます。

snowflake.configure( {ocspFailOpen: false} );
const connection = snowflake.createConnection(
    {
    account: <account>,
    ...
    }
);

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

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

ステートメントの実行

ステートメントは connection.execute() メソッドを呼び出すことで実行できます。 execute() メソッドは、 SQL テキストと complete コールバックを指定するために使用できる options オブジェクトを受け入れます。 complete コールバックは、ステートメントの実行が終了し、結果を使用する準備ができたときに呼び出されます。

var statement = connection.execute({
  sqlText: 'create database testdb',
  complete: function(err, stmt, rows) {
    if (err) {
      console.error('Failed to execute statement due to the following error: ' + err.message);
    } else {
      console.log('Successfully executed statement: ' + stmt.getSqlText());
    }
  }
});

ステートメントパラメーターのバインド

時には、ステートメント内のデータをプレースホルダーにバインドする場合があります。この方法でステートメントを実行すると、 SQL インジェクション攻撃の防止に役立つため便利です。次のステートメントを考慮します。

connection.execute({
  sqlText: 'select c1 from (select 1 as c1 union all select 2 as c1) where c1 = 1;'
});

次のバインドを使用して同じ結果を達成できます。

connection.execute({
  sqlText: 'select c1 from (select :1 as c1 union all select :2 as c1) where c1 = :1;',
  binds: [1, 2]
});

バインドの ? 構文もサポートされています。

connection.execute({
  sqlText: 'select c1 from (select ? as c1 union all select ? as c1) where c1 = ?;',
  binds: [1, 2, 1]
});

注釈

バインドできるデータのサイズ、またはバッチで結合できるデータのサイズには上限があります。詳細については、 クエリテキストサイズの制限 をご参照ください。

一括挿入の配列のバインド

データの配列のバインドは、一括 INSERT 操作でサポートされています。次のように配列の配列を渡します。

connection.execute({
  sqlText: 'insert into t(c1, c2, c3) values(?, ?, ?)',
  binds: [[1, 'string1', 2.0], [2, 'string2', 4.0], [3, 'string3', 6.0]]
});

注釈

大きな配列をバインドするとパフォーマンスに影響し、データのサイズが大きすぎてサーバーで処理できない場合は拒否される可能性があります。

ステートメントのキャンセル

statement.cancel() メソッドを呼び出すと、ステートメントをキャンセルできます。

statement.cancel(function(err, stmt) {
  if (err) {
    console.error('Unable to abort statement due to the following error: ' + err.message);
  } else {
    console.log('Successfully aborted statement');
  }
});

結果の利用

インラインによる結果の返答

結果を利用する最も一般的な方法は、 connection.execute()complete コールバックを渡すことです。ステートメントの実行が終了し、結果を使用できる状態になると、 complete コールバックが呼び出され、結果行がインラインで返されます。

connection.execute({
  sqlText: 'select * from sometable',
  complete: function(err, stmt, rows) {
    if (err) {
      console.error('Failed to execute statement due to the following error: ' + err.message);
    } else {
      console.log('Number of rows produced: ' + rows.length);
    }
  }
});

結果のストリーミング

結果を行のストリームとして使用することもできます。これは、 statement.streamRows() メソッドを呼び出すことで実行できます。これは、受信した行を使用するために使用できるNode.js Readable ストリームを返します。 Readable ストリームの詳細については、 Node.jsのドキュメント をご参照ください。

例:

var statement = connection.execute({
  sqlText: 'select * from sometable'
});

var stream = statement.streamRows();

stream.on('error', function(err) {
  console.error('Unable to consume all rows');
});

stream.on('data', function(row) {
  // consume result row...
});

stream.on('end', function() {
  console.log('All rows consumed');
});

結果のバッチ処理

デフォルトでは、 statement.streamRows() メソッドは結果のすべての行を含むストリームを生成します。ただし、結果のサブセットのみを使用する場合、または結果行をバッチで使用する場合は、 start および end 引数で streamRows() を呼び出すことができます。これらの追加オプションを指定すると、リクエストされた範囲内の行のみがストリーミングされます。

connection.execute({
  sqlText: 'select * from sometable',
  streamResult: true, // prevent rows from being returned inline in the complete callback
  complete: function(err, stmt, rows) {
    // no rows returned inline because streamResult was set to true
    console.log('rows: ' + rows); // 'rows: undefined'

    // only consume at most the last 5 rows in the result
    rows = [];
    stmt.streamRows({
      start: Math.max(0, stmt.getNumRows() - 5),
      end: stmt.getNumRows() - 1,
    })
    .on('error', function(err) {
      console.error('Unable to consume requested rows');
    })
    .on('data', function(row) {
      rows.push(row);
    })
    .on('end', function() {
      console.log('Number of rows consumed: ' + rows.length);
    });
  }
})

データ型のキャスト

結果の行が生成されると、ドライバーは対応する JavaScriptSQL 相当物にデータ型を自動的にマッピングします。たとえば、タイプ TIMESTAMP および DATE の値は JavaScript 日付オブジェクトとして返されます。

JavaScript から SQL データ型への完全なマッピングについては、以下のテーブルをご参照ください。

SQL データ型

JavaScript データ型

メモ

VARCHAR, CHAR, CHARACTER, STRING, TEXT

String

INT, INTEGER, BIGINT, SMALLINT

Number

これがデフォルトのマッピングです。セッションパラメーター JS_TREAT_INTEGER_AS_BIGINT を使用して、 JavaScript Bigintにマッピングします。

scale = 0で、NUMBER(精度、スケール)、 DECIMAL(p、s)、 NUMERIC(p、s)

Number

これがデフォルトのマッピングです。セッションパラメーター JS_TREAT_INTEGER_AS_BIGINT を使用して、 JavaScript Bigintにマッピングします。

scale > 0で、NUMBER(精度、スケール)、 DECIMAL(p、s)、 NUMERIC(p、s)

Number

FLOAT, FLOAT4, FLOAT8, DOUBLE, DOUBLE PRECISION, REAL

Number

TIMESTAMP, TIMESTAMP_LTZ, TIMESTAMP_NTZ, TIMESTAMP_TZ

Date

TIMESTAMP_NTZ 値は UTCに返されます。

DATE

Date

TIME

String

SQL の TIME データ型には JavaScript に相当するものがないため、 JavaScript 文字列にマッピングされます。

BOOLEAN

Boolean

VARIANT, ARRAY, OBJECT

JSON

Bigintとしての整数データ型の取得

デフォルトでは、Snowflake INTEGER 列( BIGINT、 NUMBER(p、0)などを含む)は JavaScriptのNumberデータ型に変換されます。ただし、有効なSnowflake整数の最大値は、有効な JavaScript Numberの最大値よりも大きくなります。Snowflakeの INTEGER 列を、 JavaScript Numberより大きな値を保存できる JavaScript Bigintに変換するには、セッションパラメーター JS_TREAT_INTEGER_AS_BIGINTを設定します。

このパラメーターを設定するには次の2つの方法があります。

  • 以下に示すように、 ALTER SESSION ステートメントを使用します。

    connection.execute( {
                        sqlText: 'ALTER SESSION SET JS_TREAT_INTEGER_AS_BIGINT = TRUE',
                        complete: function ...
                        }
                      );
    
  • 接続構成情報でパラメーターを指定します。

    var connection = snowflake.createConnection(
          {
          accessUrl: 'http://xy12345.snowflakecomputing.com',
          username: 'fakeusername',
          password: 'fakepassword',
          account: 'fakeaccount',
          jsTreatIntegerAsBigInt: true
          }
        );
    

文字列としたデータ型のフェッチ

connection.execute() が呼び出されると、 fetchAsString オプションを設定して、すべての数値または日付を強制的に文字列として返すことができます。これは以下を取得するために使用できます。

  • タイプ DATE および TIMESTAMP (またはそのバリアント)の値のフォーマットされたバージョン。

  • 精度を損なうことなく JavaScript 数に変換できない数値 SQL 型の文字列バージョン。

例:

connection.execute({
  sqlText: 'select 1.123456789123456789123456789 as "c1"',
  fetchAsString: ['Number'],
  complete: function(err, stmt, rows) {
    if (err) {
      console.error('Failed to execute statement due to the following error: ' + err.message);
    } else {
      console.log('c1: ' + rows[0].c1); // c1: 1.123456789123456789123456789
    }
  }
});

接続の終了

connection.destroy() メソッドを呼び出すことにより、接続を終了できます。これにより、実行中のステートメントの完了を待たずに、接続に関連付けられたセッションが直ちに終了します。

connection.destroy(function(err, conn) {
  if (err) {
    console.error('Unable to disconnect: ' + err.message);
  } else {
    console.log('Disconnected connection with id: ' + connection.getId());
  }
});