如何将查询结果从雪花直接上传到 S3?

Posted

技术标签:

【中文标题】如何将查询结果从雪花直接上传到 S3?【英文标题】:How to upload Query Result from Snowflake to S3 Directly? 【发布时间】:2021-12-02 11:59:16 【问题描述】:

我有一个查询接口,用户写一个SQL查询并获取结果,我们使用的仓库是雪花来查询数据并显示查询的SQL结果。我们使用 Snowflake JDBC 建立连接,Asynchronously Queue the Query 从 snowflake 获取 Query ID(UUID) 并使用 Query ID 获取状态并获取 Result。

示例代码:

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 链接以查看结果。

我试图弄清楚这种情况是否可以在雪花本身中处理,雪花可以为查询生成元数据并将结果集上传到用户定义的存储桶,这样雪花的消费者就不必这样做.我读过关于雪花流,从阶段复制。有人可以帮助我了解这是否可行,如果可行,如何实现?

有什么方法可以让我使用 QueryId 从雪花直接将查询结果上传到 S3,而无需获取并将其上传到 S3。

【问题讨论】:

【参考方案1】:

您可以使用 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())));

您要使用前一个选择中的 COPY 的原因是 COPY 命令在用于查询的方面有些限制。通过首先将查询作为常规选择运行,然后从该结果运行 select *,您就可以克服这些限制。

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

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

【讨论】:

是的,这很好用,但是我发现没有选项可以将结果集与元数据一起转换为 JSON 并将其直接上传到 S3。 我看看结果集中是否没有行使用复制功能时csv上传不成功。

以上是关于如何将查询结果从雪花直接上传到 S3?的主要内容,如果未能解决你的问题,请参考以下文章

使用签名的 url 将文件从 angularjs 直接上传到 amazon s3

Rails 直接上传到 Amazon S3

Rails + CarrierwaveDirect:成功直接上传到S3后无法下载和处理图像

不使用生产服务器直接上传到 s3

AWS - CORS 无法将文件直接上传到 S3

如何将 Pandas 数据框直接上传到 BigQuery?