如何将 Snowflake 的查询结果直接上传到 S3?

How to upload Query Result from Snowflake to S3 Directly?

我有一个查询界面,用户可以在其中编写 SQL 查询并获取结果,我们使用的仓库是 Snowflake 来查询数据并显示查询的 SQL 结果。我们使用 Snowflake JDBC 建立连接,异步排队查询从 snowflake 获取查询 ID(UUID)并使用查询 ID 获取状态并获取结果。

示例代码:

try {
            ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
            int numColumns = resultSetMetaData.getColumnCount();

            for (int i = 1; i <= numColumns; i++) {
                arrayNode.add(objectMapper.createObjectNode().put("name", resultSetMetaData.getColumnName(i))
                        .put("attribute_number", i)
                        .put("data_type", resultSetMetaData.getColumnTypeName(i))
                        .put("type_modifier", (Short) null)
                        .put("scale", resultSetMetaData.getScale(i)).put("precision",
                                resultSetMetaData.getPrecision(i)));
            }
            rootNode.set("metadata", arrayNode);
            arrayNode = objectMapper.createArrayNode();
            while (resultSet.next()) {
                ObjectNode resultObjectNode = objectMapper.createObjectNode();
                for (int i = 1; i <= numColumns; i++) {
                    String columnName = resultSetMetaData.getColumnName(i);
                    resultObjectNode.put(columnName, resultSet.getString(i));
                }
                arrayNode.add(resultObjectNode);
            }
            rootNode.set("results", arrayNode);
            // TODO: Instead of returning the entire result string, send it in chunk to S3 utility class for upload
            resultSet.close();
            jsonString = objectMapper.writeValueAsString(rootNode);
        }

正如您在此处看到的,我们的用例是我们需要将元数据信息(列详细信息)与结果一起发送。然后将结果集上传到 S3,并为用户提供一个 S3 link 以查看结果。

您可以使用 COPY 命令将结果存储在 S3 存储桶中。这是一个简化的示例,显示了临时内部阶段的过程。对于您的用例,您将在 S3 中创建和使用外部阶段:

create temp stage FOO;
select * from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."NATION";
copy into @FOO from (select * from table(result_scan(last_query_id())));

您想使用之前 select 中的 COPY 的原因是 COPY 命令在可用于查询的内容方面有所限制。通过 运行 查询作为常规 select 首先,然后 运行 a select * 从该结果中,您可以克服这些限制。

COPY 命令支持其他文件格式。这种方式将使用默认的 CSV 格式。您还可以指定 JSON、Parquet 或使用命名文件格式的自定义分隔格式。

https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html