/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 ]-
Максимальное время (в миллисекундах), выделяемое на исполнение запроса с учетом всех порций данных. После его истечения система принудительно завершает запрос.
Параметр применяется при потоковом чтении данных. Если он не задан или его значение равно
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"
}
]
}'