关于 eventhouse-authoring-cli
这是用于在 Microsoft Fabric 中编写和管理 Eventhouse 资源的 CLI 技能,面向数据从业者和 Agent,提供 KQL 命令、数据摄取、架构变更、策略及运行检查指引。
主要功能
- 01创建和修改表
- 02摄取内联数据及存储数据
- 03设置保留和缓存策略
- 04创建物化视图和函数
- 05部署架构变更并检查操作
适用场景
- 01创建表并摄取测试记录
- 02从存储或 OneLake 加载数据
- 03应用保留或缓存策略
- 04部署架构更新并检查操作状态
MCP 相关
README 描述了使用 `az` CLI 和 Kusto REST 执行 KQL 管理命令的流程;未提及 MCP 服务或工具。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ skills-for-fabric --skill eventhouse-authoring-cli安装后在 Claude Code 中输入/eventhouse-authoring-cli确认已加载。
附带文件references/authoring-script-templates.md
详细介绍
更新检查 — 每个会话仅检查一次(强制) 首次在某个会话中使用此技能时,必须先运行 check-updates 技能,再继续操作。
- GitHub Copilot CLI / VS Code:调用
check-updates技能。- Claude Code / Cowork / Cursor / Windsurf / Codex:比较本地与远程
package.json版本。- 如果本会话之前已执行过检查,则跳过。
重要说明
- 要根据工作区名称查找工作区详情(包括其 ID):先列出所有工作区,然后使用 JMESPath 进行筛选。
- 要根据工作区 ID、项类型和项名称查找项详情(包括其 ID):先列出该工作区中该类型的所有项,然后使用 JMESPath 进行筛选。
eventhouse-authoring-cli — 通过 CLI 创建和管理 Eventhouse
目录
工具栈
| 工具 | 用途 | 安装 |
|---|---|---|
| az cli | 通过 Kusto REST API 执行 KQL 管理命令;发现 Fabric 控制平面 | winget install Microsoft.AzureCLI |
| jq | 处理 JSON 并格式化输出 | winget install jqlang.jq |
连接
与 eventhouse-consumption-cli 相同。创作操作需要更高权限的角色:
# Discover KQL Database query URI
WS_ID="<workspace-id>"
az rest --method GET \
--url "https://api.fabric.microsoft.com/v1/workspaces/${WS_ID}/kqlDatabases" \
--resource "https://api.fabric.microsoft.com" \
| jq '.value[] | {name: .displayName, queryUri: .properties.queryServiceUri}'
# Set connection variables
CLUSTER_URI="https://<cluster>.kusto.fabric.microsoft.com"
DB_NAME="MyDatabase"
# Verify admin access
cat > /tmp/kql_body.json << EOF
{"db":"${DB_NAME}","csl":".show database ${DB_NAME} principals | where Role == 'Admin'"}
EOF
az rest --method POST \
--url "${CLUSTER_URI}/v1/rest/mgmt" \
--resource "https://kusto.kusto.windows.net" \
--headers "Content-Type=application/json" \
--body @/tmp/kql_body.json \
| jq '.Tables[0].Rows'
创作范围
| 操作 | 命令模式 |
|---|---|
| 创建表 | .create-merge table T (cols) |
| 添加列 | .alter-merge table T (NewCol: type) |
| 删除表 | .drop table T ifexists |
| 摄取数据 | .ingest into table T (...) |
| 设置保留策略 | .alter table T policy retention ... |
| 设置缓存 | .alter table T policy caching hot = Nd |
| 创建函数 | .create-or-alter function F() { ... } |
| 创建物化视图 | .create materialized-view MV on table T { ... } |
| 创建更新策略 | .alter table T policy update ... |
| 创建数据映射 | .create table T ingestion csv mapping ... |
执行 KQL 命令
此技能中的所有 KQL 管理命令都遵循相同的 az rest 模式。设置 CLUSTER_URI 和 DB 后,将 JSON 正文写入 /tmp/kql_body.json 并执行:
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":"<KQL management command>"}
EOF
az rest --method POST \
--url "${CLUSTER_URI}/v1/rest/mgmt" \
--resource "https://kusto.kusto.windows.net" \
--headers "Content-Type=application/json" \
--body @/tmp/kql_body.json \
| jq '.Tables[0].Rows'
嵌套 JSON — 对于 KQL 中嵌入 JSON 的命令(策略、映射),使用
<< 'EOF'(单引号)防止 Shell 展开反斜杠转义的引号,并将${DB}替换为实际的数据库名称。
PowerShell 等效写法 — 先执行
@{db=$Database;csl=$Command} | ConvertTo-Json -Compress | Out-File $env:TEMP\kql_body.json -Encoding utf8NoBOM,然后执行--body "@$env:TEMP\kql_body.json"。请参阅 PowerShell 模板。
通过 CLI 管理表
创建表(幂等)
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".create-merge table Events (Timestamp: datetime, EventType: string, UserId: string, Properties: dynamic, Duration: real)"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
添加列
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".alter-merge table Events (Region: string)"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
删除表
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".drop table Events ifexists"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
通过 CLI 摄取数据
内联摄取(测试)
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".ingest inline into table Events <| 2025-01-15T10:00:00Z,Login,user1,{},0.5\n2025-01-15T10:01:00Z,Click,user2,{},0.2"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
从存储中摄取
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".ingest into table Events (h'https://mystorage.blob.core.windows.net/data/events.csv.gz;impersonate') with (format='csv', ingestionMappingReference='EventsCsvMapping', ignoreFirstRecord=true)"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
从 OneLake 摄取
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".ingest into table Events (h'abfss://[email protected]/lakehouse.Lakehouse/Files/events.parquet;impersonate') with (format='parquet')"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
从查询执行 Set-or-Append
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".set-or-append CleanEvents <| RawEvents | where IsValid == true | project Timestamp, EventType, UserId"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
通过 CLI 配置策略
保留策略
# Set 365-day retention
cat > /tmp/kql_body.json << 'EOF'
{"db":"MyDB","csl":".alter table Events policy retention '{\"SoftDeletePeriod\":\"365.00:00:00\",\"Recoverability\":\"Enabled\"}'"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
缓存(热缓存)
# Keep last 30 days in hot cache
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".alter table Events policy caching hot = 30d"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
流式摄取
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".alter table Events policy streamingingestion enable"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
通过 CLI 管理物化视图
# Create materialized view with backfill
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".create materialized-view with (backfill=true) HourlyEventCounts on table Events { Events | summarize Count = count(), LastSeen = max(Timestamp) by EventType, bin(Timestamp, 1h) }"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
# Check health
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".show materialized-view HourlyEventCounts statistics"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
通过 CLI 管理函数和更新策略
创建函数
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".create-or-alter function with (docstring='Parse raw events', folder='ETL') ParseRawEvents() { RawEvents | extend Parsed = parse_json(RawData) | project Timestamp = todatetime(Parsed.timestamp), EventType = tostring(Parsed.eventType), UserId = tostring(Parsed.userId) }"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
创建更新策略
cat > /tmp/kql_body.json << 'EOF'
{"db":"MyDB","csl":".alter table ParsedEvents policy update @'[{\"IsEnabled\":true,\"Source\":\"RawEvents\",\"Query\":\"ParseRawEvents()\",\"IsTransactional\":true}]'"}
EOF
执行
/tmp/kql_body.json— 请参阅执行 KQL 命令
通过 CLI 演进架构
安全的架构部署脚本
将管理命令保存在 .kql 文件中(每行一条),然后通过 az rest 逐条执行:
# deploy_schema.kql contains one command per line:
# .create-merge table Events (Timestamp: datetime, EventType: string, UserId: string, Properties: dynamic)
# .create-merge table ParsedEvents (Timestamp: datetime, EventType: string, UserId: string, PageName: string)
# .alter table Events policy retention '{\"SoftDeletePeriod\":\"365.00:00:00\",\"Recoverability\":\"Enabled\"}'
# .alter table Events policy caching hot = 30d
# Execute each command from the file (see "Execute KQL Command" section)
while IFS= read -r cmd; do
[[ "$cmd" =~ ^// ]] && continue # skip comment lines
[[ -z "$cmd" ]] && continue # skip blank lines
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":"${cmd}"}
EOF
az rest --method POST \
--url "${CLUSTER_URI}/v1/rest/mgmt" \
--resource "https://kusto.kusto.windows.net" \
--headers "Content-Type=application/json" \
--body @/tmp/kql_body.json \
| jq '.Tables[0].Rows'
done < deploy_schema.kql
导出当前架构
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".show database ${DB} schema as csl script"}
EOF
az rest --method POST \
--url "${CLUSTER_URI}/v1/rest/mgmt" \
--resource "https://kusto.kusto.windows.net" \
--headers "Content-Type=application/json" \
--body @/tmp/kql_body.json \
| jq -r '.Tables[0].Rows[][0]' > current_schema.kql
监控创作操作
// Recent management commands
.show commands
| where StartedOn > ago(1h)
| project StartedOn, CommandType, Text = substring(Text, 0, 100), State, Duration
| order by StartedOn desc
// Ingestion failures
.show ingestion failures
| where FailedOn > ago(24h)
| summarize FailureCount = count() by ErrorCode, Table
| order by FailureCount desc
// Materialized view health
.show materialized-views
| project Name, IsEnabled, IsHealthy, MaterializedTo
必须 / 优先 / 避免 / 故障排除
必须遵守
- 对含糊的提示词先进行澄清,再采取行动——如果请求未指定目标表、操作类型或架构(例如“设置我的 Eventhouse”“配置我的数据库”),请询问用户想要执行什么操作。切勿自行推断意图并执行管理命令。不可逆的副作用(策略变更、架构修改、数据引入)必须得到用户明确授权。
- 使用幂等命令——
.create-merge table、.create-or-alter function、.create table ifnotexists。 - 编写前验证权限——必须具有
Admin或Ingestor角色。 - 附加更新策略前先进行测试——独立运行函数。
- 从 OneLake 或 Blob Storage 引入数据时,在存储 URI 中加入
impersonate。
优先选择
- 使用
az rest和循环部署多命令架构文件。 - 使用 Fabric KQL MCP server,构建与 Agent 集成的数据引入和管理工作流。
- 优先使用
.create-merge table,而非.create table,以安全地演进架构。 - 使用具体化视图,而非重复执行开销较大的聚合查询。
- 采用基于脚本的 CI/CD——使用
.show database DB schema as csl script导出架构并存储在 git 中。
避免
- 不带
ifexists使用.drop table——表不存在时会失败。 - 使用
.alter table添加列——请改用.alter-merge table(仅支持添加)。 - CSV/JSON 数据引入时不使用映射——列顺序或字段名称可能不匹配。
- 硬编码存储 URI——在脚本中使用参数。
- 不了解重新回填成本就禁用具体化视图。
故障排除
| 症状 | 解决方法 |
|---|---|
.create table 因“already exists”失败 | 使用 .create-merge table 或 .create table ifnotexists |
| 数据引入成功,但表为空 | 检查数据映射:.show table T ingestion csv mappings |
| 更新策略未触发 | 验证函数能否独立运行;检查 .show table T policy update |
管理命令返回 Forbidden (403) | 申请 admin 或 ingestor 数据库角色 |
| 具体化视图卡住 | 检查 .show materialized-view MV statistics;可能需要执行 .disable/.enable |
| OneLake 数据引入认证错误 | 在 abfss:// URI 中添加 ;impersonate |
Agent 工作流
编写前进行探索
执行任何操作前,务必确认用户是否有明确意图:
Step 0 → Is the request specific? Does it name a table, operation, and/or schema?
→ NO → Ask: "What would you like to set up? Options: create tables,
configure policies, set up ingestion mappings, create materialized views."
STOP — do not proceed until user specifies.
→ YES → Continue to Step 1.
Step 1 → .show tables details // what exists?
Step 2 → .show table <TABLE> schema as json // current columns
Step 3 → .show table <TABLE> policy retention // current policies
Step 4 → Plan changes (create-merge, alter, etc.)
Step 5 → Execute changes
Step 6 → Verify: .show table <TABLE> schema as json // confirm changes
脚本生成工作流
Step 1 → Understand requirements from user
Step 2 → Generate KQL management commands
Step 3 → Save to .kql file
Step 4 → Deploy via az rest (one command at a time)
Step 5 → Verify deployed state matches intent
示例
示例 1:创建带有策略和映射的表
# Create table
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".create-merge table SensorData (Timestamp: datetime, DeviceId: string, Temperature: real, Humidity: real, Location: dynamic)"}
EOF
执行
/tmp/kql_body.json——参见执行 KQL 命令
# Set retention
cat > /tmp/kql_body.json << 'EOF'
{"db":"MyDB","csl":".alter table SensorData policy retention '{\"SoftDeletePeriod\":\"90.00:00:00\",\"Recoverability\":\"Enabled\"}'"}
EOF
执行
/tmp/kql_body.json——参见执行 KQL 命令
# Set caching
cat > /tmp/kql_body.json << EOF
{"db":"${DB}","csl":".alter table SensorData policy caching hot = 7d"}
EOF
执行
/tmp/kql_body.json——参见执行 KQL 命令
# Create JSON mapping
cat > /tmp/kql_body.json << 'EOF'
{"db":"MyDB","csl":".create table SensorData ingestion json mapping 'SensorJsonMapping' '[{\"column\":\"Timestamp\",\"path\":\"$.ts\",\"datatype\":\"datetime\"},{\"column\":\"DeviceId\",\"path\":\"$.deviceId\",\"datatype\":\"string\"},{\"column\":\"Temperature\",\"path\":\"$.temp\",\"datatype\":\"real\"},{\"column\":\"Humidity\",\"path\":\"$.humidity\",\"datatype\":\"real\"},{\"column\":\"Location\",\"path\":\"$.location\",\"datatype\":\"dynamic\"}]'"}
EOF
执行
/tmp/kql_body.json——参见执行 KQL 命令
示例 2:使用更新策略的 ETL
// 1. Target table
.create-merge table ParsedLogs (Timestamp: datetime, Level: string, Message: string, Source: string)
// 2. Transform function
.create-or-alter function ParseRawLogs() {
RawLogs
| extend J = parse_json(RawMessage)
| project
Timestamp = todatetime(J.timestamp),
Level = tostring(J.level),
Message = tostring(J.message),
Source = tostring(J.source)
}
// 3. Attach update policy
.alter table ParsedLogs policy update
@'[{"IsEnabled":true,"Source":"RawLogs","Query":"ParseRawLogs()","IsTransactional":true}]'
Agent 集成说明
- 此技能涵盖编写操作——创建或更改数据库对象以及引入数据。
- 对于只读查询和数据探索,请委派给 eventhouse-consumption-cli。
- 对于跨工作负载编排,请委派给 FabricDataEngineer Agent。
- 所有管理命令都需要较高的数据库角色权限(
Admin或Ingestor)。