/datamarts[/{datamart}]/query
Содержание раздела
POST-метод выполняет запрос SQL+, заданный в теле сообщения. Поддерживается как выполнение простого вопроса, так и подготовленного запроса (prepared statement).
Запрос можно выполнить в выбранной логической базе данных. Чтобы выбрать логическую БД, укажите ее имя в URL.
Режимы выполнения запросов
Запросы на загрузку, обновление и выгрузку данных можно выполнить в синхронном или асинхронном режиме. Остальные запросы выполняются в синхронном режиме.
Режим выполнения задается параметром async
в теле запроса. По умолчанию, если параметр async
имеет значение false
или не задан, запрос исполняется в синхронном режиме и система возвращает ответ только после завершения обработки запроса; если параметр имеет значение true
, ответ возвращается при принятии запроса на обработку, а не по завершении обработки.
Формат ответа
Поддерживаемые форматы данных
Метод поддерживает возврат данных в различных форматах — JSON, Avro и plain. По умолчанию метод возвращает ответ в JSON-формате. При необходимости вы можете задать другой формат ответа с помощью параметра format в URL.
Avro-формат ответа
При использовании Avro-формата ответа в поле doc
схемы Avro возвращается информация о логических типах данных, содержащихся в выборке, как показано в примере ниже.
Для столбца с неопределенным типом в поле doc
указывается тип ANY
, а в поле fields
указывается union-элемент со всеми типами Avro (см. пример ниже для столбца test_column
). Пример запроса, в котором столбец test_column
имеет неопределенный тип данных: SELECT *, null AS test_column FROM marketing.sales
.
Пример схемы Avro в ответе, представленной для наглядности в JSON-формате:
{
"type": "record",
"name": "resultSet",
"namespace": "prostore",
"doc": {
"metadata": [
{
"name": "id",
"type": "BIGINT",
"size": null,
"nullable": false
},
{
"name": "transaction_date",
"type": "TIMESTAMP",
"size": 6,
"nullable": false
},
{
"name": "product_code",
"type": "VARCHAR",
"size": 256,
"nullable": false
},
{
"name": "product_units",
"type": "BIGINT",
"size": null,
"nullable": false
},
{
"name": "store_id",
"type": "BIGINT",
"size": null,
"nullable": false
},
{
"name": "description",
"type": "VARCHAR",
"size": 256,
"nullable": true
},
{
"name": "test_column",
"type": "ANY",
"size": null,
"nullable": true
}
]
},
"fields": [
{"name": "id", "type": "long"},
{"name": "transaction_date", "type": {"type": "long", "logicalType": "timestamp-micros"}},
{"name": "product_code", "type": {"type": "string", "avro.java.string": "String"}},
{"name": "product_units", "type": "long"},
{"name": "store_id", "type": "long"},
{"name": "description", "type": ["null", {"type": "string", "avro.java.string": "String"}], "default": null},
{"name" : "test_column", "type" : [ "null", "long", "double", "int", "float", "boolean", {"type" : "string", "avro.java.string" : "String"}], "default" : null}
]
}
Состав ответов при потоковом чтении данных
При потоковом чтении данных ответы возвращаются в следующем виде:
- в JSON-формате:
- первый ответ потока содержит массив
metadata
с логической схемой данных, а также пустые массивыresult
иstatistics
; - все последующие ответы потока содержат массив
result
с порцией записей, а также пустые массивыmetadata
иstatistics
(см. пример ниже);
- первый ответ потока содержит массив
- в Avro-формате:
- первый ответ потока содержит заголовок со схемой данных Avro (см. пример выше);
- все последующие ответы потока содержат блоки данных без заголовка и схемы;
- в plain-формате:
- первый ответ потока содержит список имен столбцов, присутствующих в выборке;
- все последующие ответы потока содержат порции записей без метаданных.
Режимы чтения данных
Метод поддерживает следующие режимы чтения данных:
- однократное чтение — возвращается один ответ с полной выборкой по запросу;
- потоковое чтение — возвращается поток из множества ответов, содержащих порции данных указанного размера.
По умолчанию метод возвращает результат чтения одним ответом, но, если в теле запроса задан параметр fetchSize, результат чтения возвращается в виде потока.
Потоковое чтение данных по HTTP API доступно только при подключении по протоколу HTTP/2 и чтении из СУБД ADB и (или) ADP. Подробнее см. в разделе Потоковое чтение данных.
URL
{baseUrl}/api/v1/datamarts[/{datamart}]/query[?format={format}[&compressionLevel={level}]]
Параметры:
baseUrl
— адрес ноды Prostore, состоящий из IP-адреса или доменного имени и номера порта;datamart
(опциональный) — имя логической базы данных, используемой по умолчанию;format
(опциональный) — формат ответа. Возможные значения:json
— JSON-строка (по умолчанию);plain
— текстовое представление;avro
— Avro-формат без сжатия;avro-deflate
— Avro-формат со сжатием по алгоритму Deflate;avro-snappy
— Avro-формат со сжатием по алгоритму Snappy;avro-bzip2
— Avro-формат со сжатием по алгоритму BZip2;avro-xz
— Avro-формат со сжатием по алгоритму XZ;avro-zstanstard
— Avro-формат со сжатием по алгоритму Zstandard;
compressionLevel
— коэффициент сжатия данных. Должен быть указан для всех перечисленных выше Avro-форматов, кромеavro
. Возможные значения коэффициента зависят от выбранного алгоритма сжатия; подробнее см. в документации Apache Avro.
Заголовки запроса
Поддерживаются следующие опциональные заголовки:
x-request-id
— задает уникальный идентификатор HTTP-запроса. Если не указан, система генерирует UUID-значение и возвращает его в качестве идентификатора в ответе;Authorization
— задает тип аутентификации и авторизационный токен (JWT). Возможное значение типа аутентификации —Bearer
.
Подробнее об аутентификации запросов см. в разделе Аутентификация.
В асинхронных запросах x-request-id
имеет ограничения на символы, описанные в секции ниже.
Ограничения x-request-id
В идентификаторах x-request-id
асинхронных запросов не поддерживаются следующие символы (подробнее см. в документации ZooKeeper):
- точка или две точки без добавления других символов;
- спецсимволы Unicode;
- строка
zookeeper
без добавления других символов.
Тело запроса
Тело запроса может содержать параметры, описанные ниже. В квадратных скобках [ parameter ]
отмечены опциональные параметры.
query
-
Запрос SQL+ из числа поддерживаемых. В простом запросе указывайте значения как есть, в подготовленном — замените каждое значение на символ
?
. [ queryId ]
-
Идентификатор запроса SQL+. Позволяет отследить обработку запроса с помощью логов.
[ maxRowsToRead ]
-
Максимальное количество строк, возвращаемых по запросу. При потоковом чтении данных значение применяется к запросу в целом, а не к отдельной порции данных.
Если параметр не задан или его значение равно0
илиnull
, количество возвращаемых записей не ограничено. [ fetchSize ]
-
Максимальное количество записей в порции данных, возвращаемой в одном ответе при потоковом чтении.
Если параметр не задан или его значение равно0
илиnull
, все записи возвращаются одним ответом со всеми данными выборки (потоковое чтение выключено).Потоковое чтение по HTTP API доступно только при подключении по протоколу HTTP/2 и чтении из СУБД ADB и (или) ADP. Подробнее см. в разделе Потоковое чтение данных.
Потоковое чтение данных недоступно в асинхронном режиме обработки запроса. При наличии в запросе параметра
async
со значениемtrue
и параметраfetchSize
со значением больше0
учитывается только параметрasync
— система выполняет запрос в асинхронном режиме и возвращает один ответ, сообщающий о начале обработки запроса (см. пример ниже). [ fetchTimeoutMs ]
-
Максимальное время (в миллисекундах) выполнения запроса с учетом всех порций данных, по истечении которого система закрывает соединение с HTTP-клиентом.
Параметр применяется только при потоковом чтении данных. Если он не задан или его значение равно0
илиnull
, то время выполнения запроса не ограничено. [ params ]
-
Список параметров подготовленного запроса:
value
— значение параметра;type
— тип данных параметра из числа логических типов данных.
async
-
Режим выполнения запроса. Возможные значения:
false
(по умолчанию) — синхронный режим выполнения;true
— асинхронный режим выполнения.
Примеры запросов
В этой секции приведены примеры как с авторизационным токеном, так и без него. Примеры без токена предназначены для случаев, когда аутентификация отключена, с токеном — для случаев, когда аутентификация включена.
Чтение данных одной порцией
Запрос без авторизационного токена:
curl -X 'POST' \
'http://localhost:9090/api/v1/datamarts/query?format=json' \
-H 'x-request-id: ee7c7570-1eec-11ed-861d-0242ac120002' \
-H 'Content-Type: application/json' \
-d '{
"query": "SELECT st.id, st.category, s.product_code FROM marketing.stores AS st INNER JOIN marketing_new.sales AS s ON st.id = s.store_id DATASOURCE_TYPE = '\''adb'\''",
"queryId": "12345",
"maxRowsToRead": 100
}'
Запрос с авторизационным токеном:
curl -X 'POST' \
'http://localhost:9090/api/v1/datamarts/query?format=json' \
-H 'x-request-id: ee7c7570-1eec-11ed-861d-0242ac120002' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' \
-d '{
"query": "SELECT st.id, st.category, s.product_code FROM marketing.stores AS st INNER JOIN marketing_new.sales AS s ON st.id = s.store_id DATASOURCE_TYPE = '\''adb'\''",
"queryId": "12345",
"maxRowsToRead": 100
}'
Потоковое чтение порциями заданного размера
Потоковое чтение данных в Avro-формате
curl -X 'POST' \
'http://localhost:9090/api/v1/datamarts/query?format=avro-zstandard&compressionLevel=10' \
-H 'x-request-id: dabf0e53-ca97-40fb-a97e-ba0b4d3088fa' \
-H 'Content-Type: application/json' \
-d '{
"query": "SELECT st.id, st.category, s.product_code FROM marketing.stores AS st INNER JOIN marketing_new.sales AS s ON st.id = s.store_id DATASOURCE_TYPE = '\''adb'\''",
"queryId": "12345",
"maxRowsToRead": 1000,
"fetchSize": 100,
"fetchTimeoutMs": 60000
}'
Потоковое чтение данных в JSON-формате
Запрос:
curl -X 'POST' \
'http://localhost:9090/api/v1/datamarts/query?format=json' \
-H 'x-request-id: 84706c2d-ba4a-4bb5-85e3-a367090f5882' \
-H 'Content-Type: application/json' \
-d '{
"query": "SELECT * FROM marketing.sales WHERE store_id = 123",
"queryId": "72848562",
"maxRowsToRead": 100,
"fetchSize": 3
}'
Первый ответ в потоке ответов:
{
"result": null,
"metadata": [
{
"name": "id",
"type": "BIGINT",
"size": null,
"nullable": false
},
{
"name": "transaction_date",
"type": "TIMESTAMP",
"size": 6,
"nullable": false
},
{
"name": "product_code",
"type": "VARCHAR",
"size": 256,
"nullable": false
},
{
"name": "product_units",
"type": "BIGINT",
"size": null,
"nullable": false
},
{
"name": "store_id",
"type": "BIGINT",
"size": null,
"nullable": false
},
{
"name": "description",
"type": "VARCHAR",
"size": 256,
"nullable": true
}
],
"rows": null,
"queryId": "84706c2d-ba4a-4bb5-85e3-a367090f5882",
"statistics": null
}
Следующий ответ в потоке ответов:
{
"result": [
{
"id": 300123,
"transaction_date": "2023-08-22 13:17:47",
"product_code": "ABC0002",
"product_units": 4,
"store_id": 123,
"description": "Покупка по акции \"Лето\""
},
{
"id": 300021,
"transaction_date": "2023-08-21 23:34:10",
"product_code": "ABC0001",
"product_units": 2,
"store_id": 123,
"description": "Покупка по акции \"1+1\""
},
{
"id": 300133,
"transaction_date": "2023-08-23 18:01:04",
"product_code": "ABC0002",
"product_units": 4,
"store_id": 123,
"description": "Покупка по акции \"Лето\""
}
],
"metadata": null,
"rows": null,
"queryId": null,
"statistics": null
}
Последний ответ в потоке с остатком записей, который может быть меньше заданного значения fetchSize
:
{
"result": [
{
"id": 300031,
"transaction_date": "2021-08-25 15:34:10",
"product_code": "ABC0001",
"product_units": 2,
"store_id": 123,
"description": "Покупка по акции \"1+1\""
},
{
"id": 11,
"transaction_date": "2021-09-11 10:23:40",
"product_code": "ABC0004",
"product_units": 2,
"store_id": 123,
"description": "Покупка по акции \"1+1\""
}
],
"metadata": null,
"rows": null,
"queryId": null,
"statistics": null
}
Обновление данных в синхронном режиме
Запрос:
curl -X 'POST' \
'http://localhost:9090/api/v1/datamarts/query?format=json' \
-H 'x-request-id: 048d4ed9-5fe3-48a2-93a2-fc95885fc037' \
-H 'Content-Type: application/json' \
-d '{
"query": "INSERT INTO marketing.sales VALUES (11, '\''2021-07-11 23:34:10'\'', '\''ABC0004'\'', 2, 123, '\''Покупка по акции \"1+1\"'\'')",
"queryId": "1y3ty4y"
}'
Ответ:
{
"result": [
{
"sysCn": 94
}
],
"metadata": [
{
"name": "sysCn",
"type": "BIGINT",
"size": null,
"nullable": false
}
],
"rows": 1,
"queryId": "1y3ty4y",
"statistics": {
"elapsedTotalMs": 454,
"elapsedDbMs": 1105
}
}
Обновление данных в асинхронном режиме
Запрос:
curl -X 'POST' \
'http://localhost:9090/api/v1/datamarts/query?format=json' \
-H 'x-request-id: 4519785b-4a9b-4d3b-b332-a39e5b56ae1d' \
-H 'Content-Type: application/json' \
-d '{
"query": "INSERT INTO marketing.sales VALUES (11, '\''2021-07-11 23:34:10'\'', '\''ABC0004'\'', 2, 123, '\''Покупка по акции \"1+1\"'\'')",
"queryId": "34678765hd6",
"async": true
}'
{
"requestId": "4519785b-4a9b-4d3b-b332-a39e5b56ae1d",
"message": "Async operation started"
}
Подготовленный запрос (prepared statement)
Запрос на обновление данных в синхронном режиме без токена:
curl -X 'POST' \
'http://localhost:9090/api/v1/datamarts/marketing/query?format=json' \
-H 'x-request-id: ee7c7570-1eec-11ed-861d-0242ac120002' \
-H 'Content-Type: application/json' \
-d '{
"query": "INSERT INTO sales (id, transaction_date, product_code, product_units, store_id) values (?, ?, ?, ?, ?), (?, ?, ?, ?, ?)",
"queryId": "98765",
"params": [
{
"value": 300014,
"type": "INT"
},
{
"value": "2022-08-23 09:34:10",
"type": "TIMESTAMP"
},
{
"value": "ABC0003",
"type": "VARCHAR"
},
{
"value": 3,
"type": "INT"
},
{
"value": 123,
"type": "INT"
},
{
"value": 300015,
"type": "INT"
},
{
"value": "2022-08-23 20:05:56",
"type": "TIMESTAMP"
},
{
"value": "ABC0001",
"type": "VARCHAR"
},
{
"value": 6,
"type": "INT"
},
{
"value": 234,
"type": "INT"
}
]
}'
Запрос на обновление данных в асинхронном режиме с токеном:
curl -X 'POST' \
'http://localhost:9090/api/v1/datamarts/marketing/query?format=json' \
-H 'x-request-id: 1f6d3043-4c54-43ca-8653-9bf090a51971' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' \
-d '{
"query": "INSERT INTO sales (id, transaction_date, product_code, product_units, store_id) values (?, ?, ?, ?, ?), (?, ?, ?, ?, ?)",
"queryId": "398775",
"async": true,
"params": [
{
"value": 300014,
"type": "INT"
},
{
"value": "2022-08-23 09:34:10",
"type": "TIMESTAMP"
},
{
"value": "ABC0003",
"type": "VARCHAR"
},
{
"value": 3,
"type": "INT"
},
{
"value": 123,
"type": "INT"
},
{
"value": 300015,
"type": "INT"
},
{
"value": "2022-08-23 20:05:56",
"type": "TIMESTAMP"
},
{
"value": "ABC0001",
"type": "VARCHAR"
},
{
"value": 6,
"type": "INT"
},
{
"value": 234,
"type": "INT"
}
]
}'