mcpField
V
visualize-semantic-model

visualize-semantic-model

github.com/revosai数据与数据库0123 次安装5 天前更新
代码仓库

关于 visualize-semantic-model

visualize-semantic-model 可将 Cube.dev YAML 定义转换为深色有向图 PNG。它解析关联和基数、识别事实主干,并调用随附渲染器生成图表。

主要功能

  1. 01解析 Cube.dev YAML 定义
  2. 02识别事实主干和关联
  3. 03标注关联键及基数
  4. 04渲染深色 PNG 图表
  5. 05在对话中内嵌显示生成图像

适用场景

  1. 01检查 Cube 模型之间的关系
  2. 02查看事实与维度的连接
  3. 03根据 cube YAML 文件生成图表

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/revosai/skills --skill visualize-semantic-model

安装后在 Claude Code 中输入/visualize-semantic-model确认已加载。

附带文件scripts/render_graph.py

详细介绍

可视化语义模型

解析 Cube.dev 模型的 cube YAML 文件,检测事实主干,然后调用捆绑的渲染器并传入 JSON 规范,渲染深色主题的有向图。

渲染器(scripts/render_graph.py)只负责布局和绘图——它从标准输入接收图规范,并输出 PNG。将其捆绑在项目中,可确保每次运行都生成视觉风格一致的结果,也无需每次都重新编写 matplotlib 代码。


步骤 1:确定 cubes 文件夹

如果用户传入了文件夹参数,就使用该文件夹。否则,默认使用 cubes/。如果文件夹不存在,请先询问用户 cube 定义所在的位置,再继续。

find <folder> -name "*.yml" -not -name "model-graph.*" | sort

步骤 2:解析 cube 图

对于每个 .yml 文件,提取:

  • spec.name — 由 ${CUBE} 和 joins 引用的 cube 标识符(metadata.name 是本地 slug,通常与之相同;如果缺少 spec.name,则回退使用它)
  • spec.meta.icon — 如果存在,则为图标键(目录键、url:… 或 data:…);不存在时为 null
  • spec.joins — target_cube → { relationship, sql } 映射
  • 从每个 join 的 sql 中解析出的简短 join 键标签

Join 键标签规则。 移除 ${CUBE}. 和 ${<target>}. 前缀。对于单个等式,使用左侧列名。对于复合键(包含多个 AND),将左侧列名用 + 连接。

sql: "${CUBE}.user_id = ${users}.user_id"
# → "user_id"

sql: "${CUBE}.traffic_source = ${rev}.traffic_source AND ${CUBE}.order_date = ${rev}.order_date"
# → "traffic_source + order_date"

基数(边始终从 一 侧指向 多 侧):

在此 cube 上声明此 cube 所在一侧另一个 cube 所在一侧
many_to_one∞1
one_to_many1∞
one_to_one11

事实主干检测。 拥有最多 many_to_one joins 的 cube(即持有外键的 cube)就是主干。如果数量相同,优先选择名称中包含 enriched、fact 或 items 的 cube。如果没有 cube 包含任何 many_to_one joins(例如,模型中所有关系都是从某个中心 cube 发出的 one_to_many),则回退到出向 joins 数量最多的 cube。如果仍无法确定,请询问用户应将哪个 cube 视为主干。

边界情况——停止并告知用户,不要渲染:

  • 文件夹中少于 2 个 cube → 至少需要两个 cube。
  • 任意位置都没有找到 joins → 没有可绘制的关系。

步骤 3:构建图规范

构建渲染器可识别的 JSON 对象:

{
  "title": "Semantic Model — <project_name>",
  "fact_spine": {
    "name": "<fact_cube>",
    "icon": "<catalog_key_or_null>",
    "pk": "<pk_col>",
    "fks": ["fk_a", "fk_b", "fk_c", "fk_d"]
  },
  "dimensions": [
    {
      "name": "<dim_cube>",
      "icon": "<catalog_key_or_null>",
      "pk": "<pk_col>",
      "extras": ["metric1", "metric2"]
    }
  ],
  "edges": [
    {
      "from": "<dim_cube>",
      "to": "<fact_cube>",
      "label": "<join_key>",
      "from_card": "1",
      "to_card": "∞"
    }
  ]
}

from_card / to_card 是渲染在箭头两端的标签——"1" 或 "∞"。对于 one_to_one joins,两端都为 "1"。

icon 字段会保留在规范中,供渲染器未来支持时使用——当前的 render_graph.py 尚不绘制图标。请包含该字段,以便升级渲染器时可使用这些数据。

无论 YAML 中声明的关系方向如何,箭头始终从维度指向事实。


步骤 4:渲染

python3 -c "import matplotlib" 2>/dev/null || python3 -m pip install matplotlib --quiet

python3 .claude/skills/visualize-semantic-model/scripts/render_graph.py \
  --output <folder>/model-graph.png \
  <<'EOF'
{ ... the JSON spec from Step 3 ... }
EOF

如果 <folder>/model-graph.png 已存在,且用户未明确要求重新生成,请在覆盖前征求同意。


步骤 5:显示结果

对 PNG 路径使用 Read 工具(不是 Python 的 Read() 调用——Read 是 Claude Code 工具),以便在聊天中内嵌显示图像:

Read <folder>/model-graph.png


最终回复模板

Generated: <folder>/model-graph.png

Cubes visualized: <n>
Fact spine:       <cube_name>
Dimensions:       <dim1>, <dim2>, ...
Edges:            <dim1> → <fact>  (<join_key>)  [1:∞]
                  <dim2> → <fact>  (<join_key>)  [1:∞]

规则

  • 始终解析 YAML——绝不对 cube 名称或关系进行硬编码。
  • 边的方向始终为 维度 → 事实(箭尾位于维度一侧,箭头位于事实一侧)。
  • 1 和 ∞ 标记的位置由渲染器根据 from_card / to_card 确定;请根据上方的基数表正确设置。
  • 未经确认,不要覆盖现有的 model-graph.png。
  • 保存后,始终使用 Read 工具在聊天中内嵌显示图像。

评论

支持 Markdown