跳到主要内容
跳到主要内容
编辑此页

查询 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 Bad Request:请求格式错误。
  • 401 Unauthorized:请求未经身份验证或权限不足。
  • 404 Not Found:未找到指定的查询端点。

错误处理

  • 确保请求包含有效的身份验证凭据。
  • 验证 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"}

在 JSONCompactEachRow 格式中使用查询变量和版本 2 的请求

查询 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 @-