Verwenden des Node.js-Treibers

Der typische Workflow für die Verwendung des Treibers ist wie folgt:

  1. Stellen Sie eine Verbindung zu Snowflake her.

  2. Führen Sie Anweisungen aus, z. B. Abfragen und DDL/DML-Befehle.

  3. Verwenden Sie die Ergebnisse.

  4. Beenden Sie die Verbindung.

Wichtig

Der Treiber unterstützt derzeit nicht die Befehle PUT und GET und kann daher nicht zum Hoch- oder Herunterladen von Dateien für das Laden/Entladen von Daten verwendet werden. Verwenden Sie stattdessen SnowSQL (CLI-Client) oder JDBC-Treiber.

Unter diesem Thema:

Herstellen einer Verbindung

Um Anweisungen in Snowflake auszuführen, müssen Sie zunächst eine Verbindung herstellen.

Beispiel:

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

Beim Herstellen einer Verbindung können Sie die im folgenden Abschnitt beschriebenen Optionen festlegen.

Erforderliche Verbindungsoptionen

account

Der volle Name Ihres Kontos (bereitgestellt von Snowflake). Beachten Sie, dass Ihr vollständiger Kontoname möglicherweise zusätzliche Segmente enthält, die die Region und die Cloudplattform angeben, wo Ihr Konto gehostet wird.

Account name examples by region

Wenn Ihr Kontoname beispielsweise xy12345 lautet:

Cloudplattform/Region

Vollständiger Kontoname

AWS

US West (Oregon)

xy12345

US East (Ohio)

xy12345.us-east-2.aws

US East (N. Virginia)

xy12345.us-east-1

US East (Commercial Gov - N. Virginia)

xy12345.us-east-1-gov.aws

Canada (Central)

xy12345.ca-central-1.aws

EU (Irland)

xy12345.eu-west-1

EU (Frankfurt)

xy12345.eu-central-1

Asia Pacific (Tokio)

xy12345.ap-northeast-1.aws

Asia Pacific (Mumbai)

xy12345.ap-south-1.aws

Asia Pacific (Singapur)

xy12345.ap-southeast-1

Asia Pacific (Sydney)

xy12345.ap-southeast-2

GCP

US Central1 (Iowa)

xy12345.us-central1.gcp

Europe West2 (London)

xy12345.europe-west2.gcp

Europe West4 (Niederlande)

xy12345.europe-west4.gcp

Azure

West US 2 (Washington)

xy12345.west-us-2.azure

East US 2 (Virginia)

xy12345.east-us-2.azure

US Gov Virginia

xy12345.us-gov-virginia.azure

Canada Central (Toronto)

xy12345.canada-central.azure

West Europe (Niederlande)

xy12345.west-europe.azure

Switzerland North (Zürich)

xy12345.switzerland-north.azure

Southeast Asia (Singapur)

xy12345.southeast-asia.azure

Australia East (New South Wales)

xy12345.australia-east.azure

Wichtig

Wenn eine der folgenden Bedingungen zutrifft, unterscheidet sich Ihr Kontoname von der oben beschriebenen Struktur:

  • Wenn Ihre Snowflake Edition VPS ist, wenden Sie sich an den Snowflake-Support, um Details zu Ihrem Kontonamen zu erhalten.

  • Wenn für Ihr Konto AWS PrivateLink aktiviert ist, muss der Kontoname ein zusätzliches privatelink-Segment enthalten. Weitere Details dazu finden Sie unter AWS PrivateLink & Snowflake.

username

Snowflake-Benutzeranmeldename, mit dem die Verbindung erfolgen soll.

password

Kennwort für den Benutzer.

regionVeraltet

ID der Region, in der sich Ihr Konto befindet.

Dieser Parameter wird nicht mehr verwendet, da die Regionsinformationen, falls erforderlich, Teil des vollständigen Kontonamens sind. Er wird hier nur aus Gründen der Abwärtskompatibilität dokumentiert.

Zusätzliche Verbindungsoptionen

database

Die Standarddatenbank, die nach dem Verbinden für die Sitzung verwendet werden soll.

schema

Das Standardschema, das nach dem Verbinden für die Sitzung verwendet werden soll.

warehouse

Das standardmäßige virtuelle Warehouse, das nach dem Verbinden für die Sitzung verwendet werden soll. Wird zum Ausführen von Abfragen, Laden von Daten usw. verwendet.

role

Die Standardsicherheitsrolle, die nach dem Verbinden für die Sitzung verwendet werden soll.

clientSessionKeepAlive

Standardmäßig kommt es bei Clientverbindungen ca. 3-4 Stunden nach Ausführung der letzten Abfrage zu einem Timeout.

Wenn der Parameter clientSessionKeepAlive auf true gesetzt ist, bleibt die Verbindung des Clients zum Server auf unbestimmte Zeit bestehen, auch wenn keine Abfragen ausgeführt werden.

Die Standardeinstellung dieses Parameters lautet false.

Wenn Sie den Parameter auf true setzen, stellen Sie sicher, dass Ihr Programm die Verbindung zum Server explizit trennt, sobald das Programm abgeschlossen ist. Trennen Sie erst die Verbindung, bevor Sie das Programm beenden.

clientSessionKeepAliveHeartbeatFrequency

(Gilt nur, wenn clientSessionKeepAlive den Wert „true“ hat)

Mit diesem Parameter wird die Häufigkeit (das Wiederholungsintervall in Sekunden) zwischen Taktmeldungen festgelegt.

Sie können sich eine Verbindungs-Taktmeldung als Ersatz für eine Abfrage und als Neustart des Timeout-Countdowns für die Verbindung vorstellen. Anders ausgedrückt: Wenn die Verbindung nach mindestens 4 Stunden Inaktivität abbrechen würde, setzt der Takt den Timer zurück, sodass das Timeout frühestens 4 Stunden nach dem letzten Takt (oder der letzten Abfrage) stattfindet.

Der Standardwert ist 3.600 Sekunden (eine Stunde). Der gültige Wertebereich liegt zwischen 900 und 3.600. Da Timeouts normalerweise nach frühestens 4 Stunden auftreten, reicht normalerweise ein Takt von einmal pro Stunde, damit die Verbindung aufrechterhalten bleibt. Taktintervalle von weniger als 3.600 Sekunden sind selten notwendig oder nützlich.

Bei einigen Verbindungsoptionen wird davon ausgegangen, dass das angegebene Datenbankobjekt (Datenbank, Schema, Warehouse oder Rolle) bereits im System vorhanden ist. Wenn das angegebene Objekt nicht vorhanden ist, wird während der Verbindung kein Standard festgelegt.

Nach dem Verbinden können alle optionalen Verbindungsoptionen auch über den Befehl USE <Objekt> eingestellt oder überschrieben werden.

Überprüfen der Netzwerkverbindung zu Snowflake mit SnowCD

Nach der Konfiguration des Treibers können Sie die Netzwerkkonnektivität zu Snowflake mit SnowCD testen und Probleme beheben.

Sie können während der Erstkonfiguration und bei Bedarf jederzeit SnowCD verwenden, um Ihre Netzwerkverbindung zu Snowflake zu testen und Probleme zu beheben.

OCSP (Online Certificate Status Protocol)

Wenn der Treiber eine Verbindung herstellt, sendet Snowflake ein Zertifikat, um zu bestätigen, dass die Verbindung zu Snowflake und nicht zu einem Host besteht, der sich als Snowflake ausgibt. Der Treiber sendet dieses Zertifikat an einen OCSP (Online Certificate Status Protocol)-Server, um zu überprüfen, ob das Zertifikat widerrufen wurde.

Wenn der Treiber den OCSP-Server nicht erreichen kann, um das Zertifikat zu überprüfen, kann beim Treiber „Fail-open“ oder „Fail-close“ auftreten.

Auswahl des Fail-open- oder Fail-close-Modus

Bei Node.js-Treiberversionen vor 1.2.0 findet standardmäßig „Fail-close“ statt. Bei Versionen ab 1.2.0 findet standardmäßig „Fail-open“ statt. Sie können das Standardverhalten überschreiben, indem Sie den globalen Parameter ocspFailOpen festlegen, bevor Sie die Methode snowflake.createConnection() aufrufen. Sie können den Parameter auf „true“ oder „false“ setzen.

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

Überprüfen der OCSP-Konnektor- oder Treiber-Version

Weitere Informationen zu Version, Konfiguration und OCSP-Verhalten von Treiber oder Konnektor finden Sie unter OCSP-Konfiguration.

Ausführen von Anweisungen

Anweisungen können durch Aufruf der Methode connection.execute() ausgeführt werden. Die execute()-Methode akzeptiert ein options-Objekt, mit dem der SQL-Text und ein complete-Callback angegeben werden können. Der complete-Callback wird aufgerufen, wenn eine Anweisung die Ausführung beendet hat und das Ergebnis zur Weiterverarbeitung bereit steht:

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

Datenbindung in Anweisungsparametern

Gelegentlich kann es sinnvoll sein, Daten in einer Anweisung mit einem Platzhalter zu verknüpfen. Die Ausführung von Anweisungen auf diese Weise ist nützlich, um Angriffe durch Einschleusung von SQL-Befehlen zu verhindern. Verwenden Sie ggf. die folgende Anweisung:

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

Das gleiche Ergebnis erzielen Sie mit den folgenden Bindungen:

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

Die ?-Syntax für Bindungen wird ebenfalls unterstützt:

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

Bemerkung

Es gibt eine Obergrenze für die Datengröße, die Sie binden oder in einem Batch kombinieren können. Weitere Details dazu finden Sie unter Begrenzung der Abfragetextgröße.

Binden eines Array für Masseneinfügen

Das Binden eines Arrays von Daten wird für INSERT-Massenoperationen unterstützt. Übergeben Sie ein Array von Arrays wie folgt:

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

Bemerkung

Das Binden eines großen Arrays wirkt sich auf die Leistung aus und kann abgelehnt werden, wenn die Datenmenge zu groß ist, um vom Server verarbeitet zu werden.

Abbrechen von Anweisungen

Eine Anweisung kann durch Aufruf der Methode statement.cancel() abgebrochen werden:

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

Verwenden von Ergebnissen

Inline-Rückgabe von Ergebnissen

Die gebräuchlichste Art, Ergebnisse zu verwenden, ist die Übergabe eines complete-Callbacks an connection.execute(). Wenn die Ausführung der Anweisung beendet und das Ergebnis zur Verwendung bereit ist, wird der complete-Callback gestartet, und die Ergebniszeilen werden inline zurückgegeben:

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

Streamen von Ergebnissen

Es ist auch möglich, ein Ergebnis in Form eines Zeilenstream zu verarbeiten. Dies kann durch Aufruf der statement.streamRows()-Methode erfolgen. Dabei wird ein Readable-Node.js-Stream zurückgegeben, der verwendet werden kann, um Zeilen direkt beim Empfangen weiterzuverarbeiten. Weitere Informationen zum Readable-Stream finden Sie in der Dokumentation zu Node.js.

Beispiel:

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

Stapelverarbeitung von Ergebnissen

Standardmäßig wird mit der statement.streamRows()-Methode ein Stream produziert, der jede Zeile im Ergebnis enthält. Wenn Sie jedoch nur eine Teilmenge des Ergebnisses weiterverwenden möchten oder wenn Ergebniszeilen in Batches verwendet werden sollen, können Sie streamRows() mit start- und end-Argumenten aufrufen. Bei Angabe dieser zusätzlichen Optionen werden nur Zeilen im geforderten Bereich gestreamt:

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

Umwandeln des Datentyps

Wenn Ergebniszeilen erzeugt werden, ordnet der Treiber SQL-Datentypen automatisch den entsprechenden JavaScript-Äquivalenten zu. Beispielsweise werden Werte der Typen TIMESTAMP und DATE als JavaScript Date-Objekte zurückgegeben.

Die vollständige Zuordnung von JavaScript zu SQL-Datentypen finden Sie in der folgenden Tabelle:

SQL-Datentyp

JavaScript-Datentyp

Anmerkungen

VARCHAR, CHAR, CHARACTER, STRING, TEXT

String

INT, INTEGER, BIGINT, SMALLINT

Number

Dies ist die Standardzuordnung. Verwenden Sie den Sitzungsparameter JS_TREAT_INTEGER_AS_BIGINT, um eine Zuordnung zu JavaScript Bigint vorzunehmen.

NUMBER(Genauigkeit, Skalierung), DECIMAL(p, s), NUMERIC(p, s), wobei scale = 0

Number

Dies ist die Standardzuordnung. Verwenden Sie den Sitzungsparameter JS_TREAT_INTEGER_AS_BIGINT, um eine Zuordnung zu JavaScript Bigint vorzunehmen.

NUMBER(Genauigkeit, Skalierung), DECIMAL(p, s), NUMERIC(p, s) wobei scale > 0

Number

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

Number

TIMESTAMP, TIMESTAMP_LTZ, TIMESTAMP_NTZ, TIMESTAMP_TZ

Date

TIMESTAMP_NTZ Werte werden in UTC zurückgegeben.

DATE

Date

TIME

String

Beachten Sie, dass der TIME-Datentyp in SQL kein Äquivalent in JavaScript hat, sodass er auf eine JavaScript-Zeichenfolge (String) abgebildet wird.

BOOLEAN

Boolean

VARIANT, ARRAY, OBJECT

JSON

Abrufen von Ganzahl-Datentypen als Bigint

Standardmäßig werden die INTEGER-Spalten von Snowflake (einschließlich BIGINT, NUMBER(p, 0) usw.) in den JavaScript-Datentyp Number konvertiert. Die größten zulässigen Snowflake-Ganzzahlwerte sind jedoch größer als die größten zulässigen JavaScript-Zahlenwerte. Um Snowflake-INTEGER-Spalten in JavaScript Bigint zu konvertieren, in denen größere Werte als JavaScript Number gespeichert werden können, legen Sie den Sitzungsparameter JS_TREAT_INTEGER_AS_BIGINT fest.

Es gibt zwei Möglichkeiten, diesen Parameter festzulegen:

  • Verwenden Sie die ALTER SESSION-Anweisung wie folgt:

    connection.execute( {
                        sqlText: 'ALTER SESSION SET JS_TREAT_INTEGER_AS_BIGINT = TRUE',
                        complete: function ...
                        }
                      );
    
  • Geben Sie den Parameter in den Verbindungskonfigurationsinformationen an:

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

Abrufen von Datentypen als Zeichenfolgen (String)

Wenn connection.execute() aufgerufen wird, kann die Option fetchAsString so eingestellt werden, dass alle Zahlen oder Daten als Zeichenfolge zurückgegeben werden. Dies kann verwendet werden, um zu Folgendes zu erhalten:

  • Formatierte Versionen von Werten des Typs DATE und TIMESTAMP (oder deren Varianten).

  • Zeichenfolgeversionen von numerischen SQL-Typen, die nicht ohne Genauigkeitsverlust in JavaScript-Zahlen umgewandelt werden können.

Beispiel:

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

Beenden einer Verbindung

Eine Verbindung kann durch Aufruf der Methode connection.destroy() beendet werden. Dadurch wird die Verbindung zur Sitzung sofort beendet, ohne darauf zu warten, dass die in Ausführung befindlichen Anweisungen abgeschlossen werden:

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