応答の処理¶
このトピックでは、 SQL API からの応答を処理する方法について説明します。
このトピックの内容:
実行の流れを理解する¶
デフォルトでは、Snowflakeはステートメントを同期的に実行し、以下のフローチャートに示されている応答コードのいずれかを返します。
上記のフローチャートに示されているように、
正常に実行された1つのステートメントを送信した場合、Snowflakeは HTTP 応答コード200と結果の行を ResultSet オブジェクトに返します。
ResultSet
オブジェクトを使用して、 結果を取得 します。単一リクエストで複数のステートメント を送信し、リクエストの処理に成功した場合、Snowflakeは HTTP 応答コード200と ResultSet オブジェクトを返します。
ResultSet
オブジェクトには、結果の行が含まれていません。代わりに、data
フィールドには「複数のステートメントが正常に実行されました」というメッセージが含まれるだけです。データを取得するには、
statementHandles
フィールドから、リクエスト内にある個々のステートメントのハンドルを取得する必要があります。各ステートメントのハンドルのためにリクエストを送信して、ステートメントの実行ステータスを確認します。 ステートメントの実行ステータスの確認およびデータの取得 をご参照ください。複数の SQL ステートメントを指定するリクエストの応答を処理するプロセスの詳細については、 リクエストでの各 SQL ステートメントの結果の取得 をご参照ください。
ステートメントの実行に45秒以上かかる場合、またはステートメントを非同期で実行するように指定した場合、Snowflakeは QueryStatus オブジェクトとともに HTTP 応答コード202を返します。
QueryStatus
オブジェクトのstatementStatusUrl
フィールドで指定されたエンドポイントにリクエストを送信して、ステートメントの実行ステータスを確認できます。 ステートメントの実行ステータスの確認およびデータの取得 をご参照ください。ステートメントの実行をキャンセルする場合は、
QueryStatus
オブジェクトのstatementHandle
フィールドのステートメントハンドルを使用して、/api/v2/statements/statementHandle/cancel
にリクエストを送信できます。 SQL ステートメントの実行のキャンセル をご参照ください。
ステートメントの実行ステータスの確認およびデータの取得¶
場合によっては、ステートメントの実行ステータスを確認するためにリクエストを送信する必要があります。
実行する SQL ステートメントを送信 すると、ステートメントの実行がまだ完了していない場合、または非同期クエリを送信した場合、Snowflakeは202応答コードを返します。
ステートメントの実行が終了したかどうかを確認するには、ステートメントのステータスを確認するリクエストを送信する必要があります。
単一リクエストで複数の SQL ステートメントを送信 した場合は、ステートメントのステータスを確認するリクエストを送信することで、個々のステートメントの結果を取得します。
どちらの場合も、 GET
リクエストを /api/v2/statements/
エンドポイントに送信し、ステートメントハンドルをパスパラメーターとして URL パスの最後に追加します。詳細については GET /api/v2/statements/{statementHandle} をご参照ください。
GET /api/v2/statements/{statementHandle}
{statementHandle}
は、確認するステートメントのハンドルです。ステートメントハンドルを取得するには、
202応答コードで応答を受信した場合、応答の本文には QueryStatus オブジェクトが含まれます。このオブジェクトの
statementHandle
フィールドから、ステートメントハンドルを取得できます。このオブジェクトの
statementStatusUrl
フィールドから、リクエストのフル URL も取得できます。{ "code": "090001", "sqlState": "00000", "message": "successfully executed", "statementHandle": "e4ce975e-f7ff-4b5e-b15e-bf25f59371ae", "statementStatusUrl": "/api/v2/statements/e4ce975e-f7ff-4b5e-b15e-bf25f59371ae" }
複数の SQL ステートメントを含むリクエストを送信した場合、応答の本文には
statementHandles
フィールドを含んだResultSet
オブジェクトが含まれます。このフィールドから、個々のステートメントのハンドルを取得できます。{ ... "statementHandles" : [ "019c9fce-0502-f1fc-0000-438300e02412", "019c9fce-0502-f1fc-0000-438300e02416" ], ... }
たとえば、次の curl
コマンドは、ハンドル e4ce975e-f7ff-4b5e-b15e-bf25f59371ae
を持つステートメントのステータスをチェックします。
curl -i -X GET \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "User-Agent: myApplicationName/1.0" \
-H "X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT" \
"https://<account_identifier>.snowflakecomputing.com/api/v2/statements/e4ce975e-f7ff-4b5e-b15e-bf25f59371ae"
条件:
jwt
は、 認証用に生成した JWT です。myApplicationName
は、アプリケーションの識別子の例です。account_identifier
は、 使用する アカウント識別子 です。
ステータスを確認するリクエストを送信すると、Snowflakeは以下のフローチャートに示された応答コードの1つを返します。
上記のフローチャートに示されているように、
ステートメントの実行が正常に終了した場合、Snowflakeは HTTP 応答コード200と結果の行を ResultSet オブジェクトに返します。
ResultSet
オブジェクトを使用して、 結果を取得 します。ステートメントの実行が完了していない場合、Snowflakeは HTTP 応答コード202を QueryStatus オブジェクトとともに返します。
このオブジェクトを使用して、 ステートメントの実行ステータスを確認 します。
ステートメントの実行中にエラーが発生した場合、Snowflake は QueryFailureStatus オブジェクトとともに HTTP 応答コード422を返します。
このオブジェクトから、 エラーに関する詳細 を取得できます。
応答からの結果の取得¶
注釈
Snowflakeバージョン5.40では、Snowflake SQL API によって返されるデータの処理方法に変更が加えられています。
このセクションでは、Snowflake SQL API の新しい機能を使用して応答から結果を取得する方法について説明します。古い、廃止された動作の使用については、 廃止された機能 をご参照ください。
実行用に SQL ステートメントを送信する か、 ステートメント実行のステータスを確認する 場合、ステートメントが正常に実行されたときに、Snowflakeは応答の本文に ResultSet オブジェクトを返します。
Snowflake API は、パーティション内のデータを返します。Snowflakeは、返されるパーティションの数と各パーティションのサイズを決定します。パーティションのサイズは可変で、特定の SQL クエリに対してSnowflakeから返されるデータの量に基づいています。
リクエストを送信すると、この応答の本文には partitionInfo
フィールドが含まれます。このフィールドにはオブジェクトの配列が含まれ、各オブジェクトはデータのパーティションを記述します。この最初のオブジェクトは、この応答で返されるデータのパーティションを記述します。残りのオブジェクトは、 partition=partition_number
を使用した後続のリクエストを送信して取得できる、追加のパーティションについて記述します。
配列内の各オブジェクトは、行数とパーティションのサイズを指定します。アプリケーションは、このパーティションメタデータを使用して、後続のリクエストに対して返されるパーティションを処理する方法を決定できます。
以下に、応答の一部の例を示します。
{
"code": "090001",
"statementHandle": "536fad38-b564-4dc5-9892-a4543504df6c",
"sqlState": "00000",
"message": "successfully executed",
"createdOn": 1597090533987,
"statementStatusUrl": "/api/v2/statements/536fad38-b564-4dc5-9892-a4543504df6c",
"resultSetMetaData" : {
"numRows" : 50000,
"format" : "jsonv2",
"partitionInfo" : [ {
"rowCount" : 12288,
"uncompressedSize" : 124067,
"compressedSize" : 29591
}, {
"rowCount" : 37712,
"uncompressedSize" : 414841,
"compressedSize" : 84469
}],
},
"data": [
["customer1", "1234 A Avenue", "98765", "2021-01-20
12:34:56.03459878"],
["customer2", "987 B Street", "98765", "2020-05-31
01:15:43.765432134"],
["customer3", "8777 C Blvd", "98765", "2019-07-01
23:12:55.123467865"],
["customer4", "64646 D Circle", "98765", "2021-08-03
13:43:23.0"]
]
}
結果に関するメタデータの取得¶
応答で返される ResultSet
オブジェクトの resultSetMetaData
フィールドには、結果セット(例: 結果の形式、返されるパーティションの数など)を説明する ResultSet_resultSetMetaData オブジェクトが含まれます。
ResultSet
オブジェクトで返される列に関するメタデータの取得¶
resultSetMetaData
フィールドには、 ResultSet
オブジェクトで返される列に関する情報が含まれています。
下記の例では、 rowType
フィールドに、 ResultSet_resultSetMetaData_rowType オブジェクトの配列が含まれます。各オブジェクトは、結果の列を表します。 type
フィールドは、列のSnowflakeデータ型を指定します。
{
"resultSetMetaData": {
"numRows": 1300,
"rowType": [
{
"name":"ROWNUM",
"type":"FIXED",
"length":0,
"precision":38,
"scale":0,
"nullable":false
}, {
"name":"ACCOUNT_NAME",
"type":"TEXT",
"length":1024,
"precision":0,
"scale":0,
"nullable":false
}, {
"name":"ADDRESS",
"type":"TEXT",
"length":16777216,
"precision":0,
"scale":0,
"nullable":true
}, {
"name":"ZIP",
"type":"TEXT",
"length":100,
"precision":0,
"scale":0,
"nullable":true
}, {
"name":"CREATED_ON",
"type":"TIMESTAMP_NTZ",
"length":0,
"precision":0,
"scale":3,
"nullable":false
}],
"partitionInfo": [{
... // Partition metadata
}]
}
}
ResultSet
オブジェクトによって返されるパーティションに関するメタデータの取得¶
クエリを実行するリクエストを送信すると、応答には、データが応答間でどのようにパーティションされるかを説明するメタデータと、データの最初のパーティションが含まれます。
resultSetMetaData
フィールドには partitionInfo
フィールドが含まれています。このフィールドにはオブジェクトの配列が含まれ、各オブジェクトはデータのパーティションを記述します。この最初のオブジェクトは、この応答で返されるデータのパーティションを記述します。残りのオブジェクトは、 partition=partition_number
を使用した後続のリクエストを送信して取得できる、追加のパーティションについて説明しています。
以下に、応答の一部の例を示します。
{
"resultSetMetaData": {
"numRows: 103477,
"format": "jsonv2"
"rowType": {
... // Column metadata.
},
"partitionInfo": [{
"rowCount": 12344,
"uncompressedSize": 14384873,
},{
"rowCount": 47387,
"uncompressedSize": 76483423,
"compressedSize": 4342748
},{
"rowCount": 43746,
"uncompressedSize": 43748274,
"compressedSize": 746323
}]
},
...
}
この例では、 partitionInfo
フィールドの最初のオブジェクトは、この応答のデータフィールドにあるデータのパーティションを記述しています。
2番目のオブジェクトは、データの2番目のパーティションを記述します。これには、47387行が含まれ、リクエストを送信することで取得できます。
GET /api/v2/statements/handle?partition=1
。
3番目のオブジェクトは、データの3番目のパーティションを記述します。これには、43746行が含まれ、リクエストを送信することで取得できます。
GET /api/v2/statements/handle?partition=2
。
結果からのデータの取得¶
応答の ResultSet
オブジェクトでは、結果は data
フィールドにあります。 data
フィールドには、 JSON の文字列の配列の配列が含まれます。例:
{
...
"data": [
["customer1", "1234 A Avenue", "98765", "2021-01-20 12:34:56.03459878"],
["customer2", "987 B Street", "98765", "2020-05-31 01:15:43.765432134"],
["customer3", "8777 C Blvd", "98765", "2019-07-01 23:12:55.123467865"],
["customer4", "64646 D Circle", "98765", "2021-08-03 13:43:23.0"]
],
...
}
配列内の各配列には、行のデータが含まれます。各配列の要素は、行のデータを表します。
結果セットのデータは、列のSnowflakeデータ型に関係なく、文字列として表現された JSON にエンコードされます。
たとえば、 NUMBER
列の値 1.0
は文字列 "1.0"
として返されます。別の例として、タイムスタンプはエポック以降のナノ秒数として返されます。たとえば、2021年1月28日木曜日10:09:37.123456789 PM のタイムスタンプは "1611871777123456789"
として返されます。
ユーザーには、文字列を適切なデータ型に変換する責任があります。
Snowflakeデータ型 に応じて(POST 送信ステートメントリクエストで 出力形式パラメーター が指定されていない場合)、Snowflakeは次の形式の文字列として値を返します。
- INT / NUMBER:
文字列内の10進数。
- FLOAT:
文字列の整数または浮動小数点数。
- VARCHAR:
文字列。
- BINARY:
文字列の16進数。
- BOOLEAN:
文字列内の「false」または「true」。
- DATE:
エポック(例:
18262
)以降の日数の整数値(文字列)。- TIME, TIMESTAMP_LTZ, TIMESTAMP_NTZ:
エポック(例:
82919.000000000
)以降の秒数の浮動小数点値(小数点以下9桁)。- TIMESTAMP_TZ:
エポック以降の秒数の浮動小数点値(小数点以下9桁)、その後にスペースと分単位のタイムゾーンオフセットが続きます(例:
1616173619000000000 960
)
追加のパーティションの取得¶
Snowflake SQL API は、パーティション内のデータを返します。最初のパーティションは JSON 形式で返され、特定のクエリに対して返されるすべてのパーティションに関するメタデータが含まれます。アプリケーションは、このパーティションメタデータを使用して、後続のリクエストに対して返されるパーティションを処理する方法を決定できます。
データの最初のパーティションを含む応答を受信した後に、 partition=partition_number
を使用してリクエストを送信すると、残りのパーティションを取得できます。この partition_number
は、返すデータのパーティションを識別します。パーティション番号 0
は、最初のリクエストで返されるデータの最初のパーティションを識別します。
たとえば、データの最初のパーティションを受信した後に、パーティションパラメーターを 1
に設定してリクエストを送信すると、データの2番目のパーティションを取得できます。
GET /api/v2/statements/<handle>?partition=1
GET /api/v2/statements/<handle>?partition=partition_number
リクエストの応答では、本文に JSON データが圧縮形式で含まれています(gzipを使用)。
応答には HTTP ヘッダー Content-Encoding: gzip
が含まれます。これは、応答の本文が圧縮されていることを示します。
これらの応答にはメタデータは含まれません。すべてのパーティションのメタデータは、最初のパーティションで提供されます。
SQL NULL 値を文字列として返す¶
デフォルトでは、SQL NULL の値は null
の値として返されます。
"data" : [ [ null ], ... ]
代わりに、これらの値を文字列 "null"
として返す場合は、 実行のための SQL ステートメントを送信する POST リクエスト にある nullable
クエリパラメーターを false
に設定します。例:
POST /api/v2/statements?nullable=false
これは、SQL NULL 値を "null"
として返します。
"data" : [ [ "null" ], ... ]
注釈
ステートメントのステータスを確認する GET リクエスト で nullable
パラメーター指定することはできません。
クエリ結果の出力のフォーマット¶
Snowflake SQL API は、出力をフォーマットするためのパラメーターをサポートします(例: 日付、時刻、およびタイムスタンプのセッションパラメーター)。
たとえば、デフォルトでは、2019-03-27のような DATE 値は「17982」として返されます(2019-03-27は、エポックから17982日後)。リクエストで DATE_OUTPUT_FORMAT を「MM/DD/YY」にするように指定した場合、
{
"statement": "select date_column from mytable",
"resultSetMetaData": {
"format": "jsonv2",
},
"parameters": {
"DATE_OUTPUT_FORMAT": "MM/DD/YYYY"
}
...
}
DATE 値は「03/27/2019」として返されます。
リクエストの本文の parameters
フィールドで、データの出力形式を決定する次のパラメーターを設定できます。
BINARY_OUTPUT_FORMAT
DATE_OUTPUT_FORMAT
TIME_OUTPUT_FORMAT
TIMESTAMP_LTZ_OUTPUT_FORMAT
TIMESTAMP_NTZ_OUTPUT_FORMAT
TIMESTAMP_TZ_OUTPUT_FORMAT
TIMESTAMP_OUTPUT_FORMAT
TIMEZONE
注釈
Snowflakeは、これらのパラメーターのアカウントレベルおよびユーザーレベルの設定を無視します。SQL API 結果の値の形式を変更するには、リクエストの本文でこれらの出力パラメーターを設定する必要があります。
resultSet
オブジェクトに行番号を含める¶
行番号は結果セットで返されません。応答に行番号を含めるには、クエリで SEQUENCE または ROW_NUMBER ウィンドウ関数を呼び出して行番号を生成します。