Как напрямую загрузить результат запроса из Snowflake в S3?

#jdbc #snowflake-cloud-data-platform

#jdbc #snowflake-cloud-data-platform

Вопрос:

У меня есть интерфейс запроса, в котором пользователь пишет SQL-запрос и получает результат, хранилище, которое мы используем, — это Snowflake для запроса данных и отображения запрошенного результата SQL. Мы используем Snowflake JDBC для установления соединения, асинхронной постановки запроса в очередь, получения идентификатора запроса (UUID) от snowflake и использования идентификатора запроса для получения статуса и извлечения результата.

Пример кода:

 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 для просмотра результатов.

  • Я пытаюсь выяснить, можно ли обработать этот сценарий в самой Snowflake, где snowflake может генерировать метаданные для запроса и загружать результирующий набор в определяемую пользователем корзину, чтобы потребителям Snowflake не приходилось этого делать. Я прочитал о потоке Snowflake, скопируйте из этапов. Может кто-нибудь помочь мне понять, возможно ли это, и если да, то как этого можно достичь?
  • Есть ли какой-либо способ, которым я могу загрузить результат запроса с использованием QueryId из snowflake в S3 напрямую, не извлекая и не загружая его в S3.

Ответ №1:

Вы можете сохранить результаты в корзине S3 с помощью команды COPY . Это упрощенный пример, показывающий процесс на временной внутренней стадии. Для вашего варианта использования вы должны создать и использовать внешний этап в 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, а затем выполнив select * из этого результата, вы преодолеете эти ограничения.

Команда КОПИРОВАНИЯ поддерживает другие форматы файлов. Этот способ будет использовать формат CSV по умолчанию. Вы также можете указать формат JSON, Parquet или пользовательский формат с разделителями, используя формат именованного файла.

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

Комментарии:

1. Да, это работает нормально, однако я вижу, что нет вариантов преобразовать результирующий набор в JSON вместе с метаданными и загрузить его непосредственно в S3.

2. Я вижу, что если в результирующем наборе нет строк, загрузка csv не выполняется при использовании функций копирования.