跳至主要内容

查询 API 端点

Beta 功能。 了解更多。

**查询 API 端点** 功能允许您直接从 ClickHouse Cloud 控制台中的任何已保存 SQL 查询创建 API 端点。您将能够通过 HTTP 访问 API 端点以执行已保存的查询,而无需通过本机驱动程序连接到您的 ClickHouse Cloud 服务。

快速入门指南

在继续之前,请确保您拥有 API 密钥和管理员控制台角色。您可以按照本指南进行操作,以创建 API 密钥

创建已保存的查询

如果您拥有已保存的查询,则可以跳过此步骤。

打开一个新的查询选项卡。出于演示目的,我们将使用youtube 数据集,该数据集包含大约 45 亿条记录。例如,我们将返回在用户输入的year参数中按每个视频的平均观看次数排列的前 10 位上传者

with sum(view_count) as view_sum,
round(view_sum / num_uploads, 2) as per_upload
select
uploader,
count() as num_uploads,
formatReadableQuantity(view_sum) as total_views,
formatReadableQuantity(per_upload) as views_per_video
from
youtube
where
toYear(upload_date) = {year: UInt16}
group by uploader
order by per_upload desc
limit 10

请注意,此查询包含一个参数 (year)。SQL 控制台查询编辑器会自动检测 ClickHouse 查询参数表达式,并为每个参数提供输入。让我们快速运行此查询,以确保其有效

Test the example query

下一步,我们将继续保存查询

Save example query

有关已保存查询的更多文档,请点击此处

配置查询 API 端点

查询 API 端点可以直接从查询视图中配置,方法是单击**分享**按钮并选择API 端点。系统会提示您指定哪些 API 密钥应该能够访问该端点

Configure query endpoint

选择 API 密钥后,查询 API 端点将自动预配。将显示一个示例curl命令,以便您可以发送测试请求

Endpoint curl command

查询 API 参数

查询中的查询参数可以用语法{parameter_name: type}指定。这些参数将被自动检测,并且示例请求有效负载将包含一个queryVariables对象,您可以通过该对象传递这些参数。

测试和监控

创建查询 API 端点后,您可以使用curl或任何其他 HTTP 客户端来测试其是否有效

endpoint curl test

发送第一个请求后,**分享**按钮的右侧会立即出现一个新按钮。单击它将打开一个包含查询监控数据的弹出窗口

Endpoint monitoring

实现细节

描述

此路由在指定的查询端点上运行查询。它支持不同的版本、格式和查询变量。响应可以是流式传输的(仅限版本 2)或作为单个有效负载返回。

身份验证

  • 必填:是
  • 方法:通过 OpenAPI 密钥/密钥进行基本身份验证
  • 权限:查询端点的适当权限。

URL 参数

  • queryEndpointId(必填):要运行的查询端点的唯一标识符。

查询参数

V1

V2

  • format(可选):响应的格式。支持 ClickHouse 支持的所有格式。
  • param_:name 要在查询中使用的查询变量。name应与查询中的变量名称匹配。这仅应在请求的主体为流时使用。
  • :clickhouse_setting 任何支持的ClickHouse 设置都可以作为查询参数传递。

标题

  • x-clickhouse-endpoint-version(可选):查询端点的版本。支持的版本为12。如果未提供,则默认版本为端点的最后保存版本。
  • x-clickhouse-endpoint-upgrade(可选):将此标题设置为升级端点版本。这与x-clickhouse-endpoint-version标题一起使用。

请求正文

  • queryVariables(可选):包含要用于查询的变量的对象。
  • format(可选):响应的格式。如果查询 API 端点为版本 2,则可以使用任何 ClickHouse 支持的格式。v1 支持的格式包括
    • TabSeparated
    • TabSeparatedWithNames
    • TabSeparatedWithNamesAndTypes
    • JSON
    • JSONEachRow
    • CSV
    • CSVWithNames
    • CSVWithNamesAndTypes

响应

  • 200 OK:查询已成功执行。
  • 400 错误请求:请求格式错误。
  • 401 未授权:请求在未进行身份验证或权限不足的情况下发出。
  • 404 未找到:未找到指定的查询端点。

错误处理

  • 确保请求包含有效的身份验证凭据。
  • 验证queryEndpointIdqueryVariables以确保它们正确。
  • 以优雅的方式处理任何服务器错误,并返回适当的错误消息。

升级端点版本

要将端点版本从v1升级到v2,请在请求中包含x-clickhouse-endpoint-upgrade标题,并将其设置为1。这将触发升级过程,并允许您使用v2中提供的功能和改进。

示例

基本请求

查询 API 端点 SQL

SELECT database, name as num_tables FROM system.tables limit 3;

版本 1

cURL

curl -X POST 'https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run' \
--user '<openApiKeyId:openApiKeySecret>' \
-H 'Content-Type: application/json' \
-d '{ "format": "JSONEachRow" }'

JavaScript

fetch(
"https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run",
{
method: "POST",
headers: {
Authorization: "Basic <base64_encoded_credentials>",
"Content-Type": "application/json",
},
body: JSON.stringify({
format: "JSONEachRow",
}),
}
)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));

响应

{
"data": {
"columns": [
{
"name": "database",
"type": "String"
},
{
"name": "num_tables",
"type": "String"
}
],
"rows": [
["INFORMATION_SCHEMA", "COLUMNS"],
["INFORMATION_SCHEMA", "KEY_COLUMN_USAGE"],
["INFORMATION_SCHEMA", "REFERENTIAL_CONSTRAINTS"]
]
}
}

版本 2

cURL

curl -X POST 'https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=JSONEachRow' \
--user '<openApiKeyId:openApiKeySecret>' \
-H 'Content-Type: application/json' \
-H 'x-clickhouse-endpoint-version: 2'

JavaScript

fetch(
"https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=JSONEachRow",
{
method: "POST",
headers: {
Authorization: "Basic <base64_encoded_credentials>",
"Content-Type": "application/json",
"x-clickhouse-endpoint-version": "2",
},
}
)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));

响应

{"database":"INFORMATION_SCHEMA","num_tables":"COLUMNS"}
{"database":"INFORMATION_SCHEMA","num_tables":"KEY_COLUMN_USAGE"}
{"database":"INFORMATION_SCHEMA","num_tables":"REFERENTIAL_CONSTRAINTS"}

具有查询变量和版本 2 的 JSONCompactEachRow 格式请求

查询 API 端点 SQL

SELECT name, database FROM system.tables WHERE match(name, {tableNameRegex: String}) AND database = {database: String};

cURL

curl -X POST 'https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=JSONCompactEachRow' \
--user '<openApiKeyId:openApiKeySecret>' \
-H 'Content-Type: application/json' \
-H 'x-clickhouse-endpoint-version: 2' \
-d '{ "queryVariables": { "tableNameRegex": "query.*", "database": "system" } }'

JavaScript

fetch(
"https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=JSONCompactEachRow",
{
method: "POST",
headers: {
Authorization: "Basic <base64_encoded_credentials>",
"Content-Type": "application/json",
"x-clickhouse-endpoint-version": "2",
},
body: JSON.stringify({
queryVariables: {
tableNameRegex: "query.*",
database: "system",
},
}),
}
)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));

响应

["query_cache", "system"]
["query_log", "system"]
["query_views_log", "system"]

具有查询变量中的数组,用于将数据插入表的请求

表格 SQL

CREATE TABLE default.t_arr
(
`arr` Array(Array(Array(UInt32)))
)
ENGINE = MergeTree
ORDER BY tuple()

查询 API 端点 SQL

  INSERT INTO default.t_arr VALUES ({arr: Array(Array(Array(UInt32)))});

cURL

curl -X POST 'https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run' \
--user '<openApiKeyId:openApiKeySecret>' \
-H 'Content-Type: application/json' \
-H 'x-clickhouse-endpoint-version: 2' \
-d '{
"queryVariables": {
"arr": [[[12, 13, 0, 1], [12]]]
}
}'

JavaScript

fetch(
"https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run",
{
method: "POST",
headers: {
Authorization: "Basic <base64_encoded_credentials>",
"Content-Type": "application/json",
"x-clickhouse-endpoint-version": "2",
},
body: JSON.stringify({
queryVariables: {
arr: [[[12, 13, 0, 1], [12]]],
},
}),
}
)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));

响应

OK

具有 ClickHouse 设置 max_threads 设置为 8 的请求`

查询 API 端点 SQL

SELECT * from system.tables;

cURL

curl -X POST 'https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?max_threads=8,' \
--user '<openApiKeyId:openApiKeySecret>' \
-H 'Content-Type: application/json' \
-H 'x-clickhouse-endpoint-version: 2' \

JavaScript

fetch(
"https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?max_threads=8",
{
method: "POST",
headers: {
Authorization: "Basic <base64_encoded_credentials>",
"Content-Type": "application/json",
"x-clickhouse-endpoint-version": "2",
},
}
)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));

请求并以流的形式解析响应`

查询 API 端点 SQL

SELECT name, database from system.tables;

Typescript

async function fetchAndLogChunks(
url: string,
openApiKeyId: string,
openApiKeySecret: string
) {
const auth = Buffer.from(`${openApiKeyId}:${openApiKeySecret}`).toString(
"base64"
);

const headers = {
Authorization: `Basic ${auth}`,
"x-clickhouse-endpoint-version": "2",
};

const response = await fetch(url, {
headers,
method: "POST",
body: JSON.stringify({ format: "JSONEachRow" }),
});

if (!response.ok) {
console.error(`HTTP error! Status: ${response.status}`);
return;
}

const reader = response.body as unknown as Readable;
reader.on("data", (chunk) => {
console.log(chunk.toString());
});

reader.on("end", () => {
console.log("Stream ended.");
});

reader.on("error", (err) => {
console.error("Stream error:", err);
});
}

const endpointUrl =
"https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=JSONEachRow";
const openApiKeyId = "<myOpenApiKeyId>";
const openApiKeySecret = "<myOpenApiKeySecret>";
// Usage example
fetchAndLogChunks(endpointUrl, openApiKeyId, openApiKeySecret).catch((err) =>
console.error(err)
);

输出

> npx tsx index.ts
> {"name":"COLUMNS","database":"INFORMATION_SCHEMA"}
> {"name":"KEY_COLUMN_USAGE","database":"INFORMATION_SCHEMA"}
...
> Stream ended.

将文件中的流插入到表中

创建一个文件 ./samples/my_first_table_2024-07-11.csv,其内容如下

"user_id","json","name"
"1","{""name"":""John"",""age"":30}","John"
"2","{""name"":""Jane"",""age"":25}","Jane"

创建表 SQL

create table default.my_first_table
(
user_id String,
json String,
name String,
) ENGINE = MergeTree()
ORDER BY user_id;

查询 API 端点 SQL

INSERT INTO default.my_first_table

cURL

cat ./samples/my_first_table_2024-07-11.csv | curl --user '<openApiKeyId:openApiKeySecret>' \
-X POST \
-H 'Content-Type: application/octet-stream' \
-H 'x-clickhouse-endpoint-version: 2' \
"https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=CSV" \
--data-binary @-