Node.jsドライバーの使用

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

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

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

  3. 結果を利用します。

  4. 接続を終了します。

重要

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

このトピックの内容:

接続の確立

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

例:

// 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();
            }
        }
    );

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

必要な接続オプション

account

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

Account name examples by region

アカウント名が xy12345 の場合:

クラウドプラットフォーム/地域

完全なアカウント名

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

EU (フランクフルト)

xy12345.eu-central-1

アジア太平洋(東京)

xy12345.ap-northeast-1.aws

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

xy12345.ap-south-1.aws

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

xy12345.ap-southeast-1

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

xy12345.ap-southeast-2

GCP

US 中央部1(アイオワ)

xy12345.us-central1.gcp

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

xy12345.europe-west2.gcp

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

xy12345.europe-west4.gcp

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 がアカウントで有効になっている場合、アカウント名には追加の privatelink セグメントが 必要 です。詳細については、 AWS PrivateLink とSnowflake をご参照ください。

username

接続するSnowflakeユーザーログイン名。

password

ユーザーのパスワード。

region --- 廃止

アカウントが存在する 地域 の ID。

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

追加の接続オプション

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> コマンドで設定または上書きすることもできます。

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());
  }
});