Fabric graph
Personal Claude Code config — skills, subagents, hooks, and rules for Microsoft Fabric and Power BI workflows on Windows. Cherry-pickable, no semver.
npx -y skills add wardawgmalvicious/claude-config --skill fabric-graphAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use for Microsoft Fabric Graph (the GraphModel item, GA June 2026) — a labeled property graph modeled over OneLake Delta tables and queried with GQL (ISO/IEC 39075), distinct from openCypher/Cypher and from the KQL graph operators in Eventhouse. Covers the GraphModel REST path and GQL Query API (`POST /v1/workspaces/{ws}/GraphModels/{id}/executeQuery?preview=true` — app errors return HTTP 200 with GQL status codes), GQL query syntax and graph-type DDL (`(:Label => {prop :: TYPE NOT NULL})`, `CONSTRAINT ... REQUIRE (n.id) IS KEY`, `=>` inheritance, `ABSTRACT`, `+=`, `<:` refs), the item-definition JSON (dataSources / graphDefinition nodeTables+edgeTables / graphType / stylingConfiguration), save-triggers-ingest refresh, and gotchas (GQL is read-only — no DML, load via data management; no schema evolution — reingest; edges have exactly one label; no DROP GRAPH in GQL; NL2GQL still preview). Use whenever a user mentions Fabric graph models, GQL, property graphs over OneLake, or GraphModel items.
SKILL.md
10.2 KB, as published. Nobody here has run it
Microsoft Fabric Graph (GraphModel item)
Graph in Fabric models a labeled property graph directly over OneLake Delta tables — no ETL, no data duplication. You define node/edge types and map them to columns; on save, Fabric ingests the tables and builds a read-optimized queryable graph. Query it with GQL (the ISO/IEC 39075 standard) via UI, REST, or NL2GQL.
Item type name: GraphModel (this is the fabric-cli .GraphModel suffix and the REST collection /GraphModels). New item → Analyze and train data → Graph model.
Three things that catch people out
- It is NOT the KQL graph operators. Fabric Graph (GraphModel) is a separate workload from the
make-graph/graph-match/#crp query_language=gqlstory in Eventhouse/KQL (see fabric-eventhouse). Same word "graph", different engine, different API, different syntax surface. Don't cross-apply. - GQL is read-only here. You cannot
INSERT/SET/DELETEgraph data through GQL. Data is loaded and refreshed via data management (save the model = reingest from OneLake).CREATE GRAPHis only partially supported andDROP GRAPHis not in GQL — drop via the Fabric UI or REST API instead. - No schema evolution. Once nodes/edges/properties are modeled and data is ingested, the structure is fixed. Adding a property, changing a label, or changing a relationship type means reingesting source data into a new model. Plan the schema up front.
GQL query language (ISO/IEC 39075)
GQL expresses relationships as visual patterns instead of joins. Roots are SQL + openCypher, but it is its own dialect — do not assume Cypher syntax (e.g. no CREATE (n:Label) data writes here).
MATCH (c:Customer)-[:purchases]->(o:`Order`)
RETURN c.fullName AS customer_name, count(o) AS num_orders
GROUP BY customer_name
ORDER BY num_orders DESC
LIMIT 5
- Backtick-quote labels that collide with keywords:
(o:`Order`). ||is string concatenation:person.firstName || ' ' || person.lastName.- Undirected match
-[:knows]-is allowed in patterns, but the graph itself has no undirected edges — every edge is directed and has exactly one label. - Comments:
--line,//line,/* */block.
Graph-type DDL (defining the schema in GQL)
The graph type (schema) uses a compact DDL that is unlike anything in training-data Cypher. Get this exact, or a model will invent invalid syntax:
-- node type with typed properties; :: is the type operator
(:Person => {
id :: UINT64 NOT NULL,
firstName :: STRING,
birthday :: UINT64
}),
-- key constraint (node identity)
CONSTRAINT person_pk FOR (n:Person) REQUIRE (n.id) IS KEY,
-- inheritance with => (abstract base, then subtypes)
ABSTRACT (:Place => { id :: UINT64 NOT NULL, name :: STRING }),
(:City => :Place),
(:Country => :Place),
-- property extension with +=
(:Post => :Message += { language :: STRING, imageFile :: STRING }),
-- edge types: source -[:label {props}]-> destination
(:Person)-[:knows { creationDate :: ZONED DATETIME }]->(:Person),
(:Person)-[:studyAt { classYear :: UINT64 }]->(:University),
-- <: references an abstract type
(:Comment)-[:replyOf]->(<:Message)
Full social-network schema example + the GQL standard-conformance table (what's supported vs not) → references/REFERENCE.md.
GQL Query API (REST)
Single RPC-over-HTTP endpoint — the current documented URL carries ?preview=true:
az rest --method post \
--resource "https://api.fabric.microsoft.com" \
--url "https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/GraphModels/{graphModelId}/executeQuery?preview=true" \
--headers "Content-Type=application/json" "Accept=application/json" \
--body '{ "query": "MATCH (n:Person) WHERE n.birthday > 19800101 RETURN n.firstName, n.lastName LIMIT 100" }'
- Token audience is
https://api.fabric.microsoft.com(az account get-access-token --resource https://api.fabric.microsoft.com). See fabric-auth. - List graphs in a workspace:
GET /v1/workspaces/{workspaceId}/GraphModels. - Application errors return HTTP 200, not 4xx. You MUST inspect the GQL
status.code(6-char string):00/01/02/03prefixes = success (possibly with warnings); anything else is an error, with detail instatus.diagnosticsand chainedstatus.cause. Do not assume success from HTTP 200. - Result is a discriminated union on
result.kind(TABLEwithcolumns+data, orNOTHING). Values carrygqlType; largeINT64/UINT64outside JS safe range and floatInf/-Inf/NaNarrive as strings.
Request/response schema, value-encoding table, and status-code families → references/REFERENCE.md.
Graph Model item-definition JSON (automation / CI-CD)
For createItemWithDefinition / getDefinition / updateDefinition (see fabric-tmdl-api for the envelope, LRO, base64, all-parts rules), a GraphModel definition has four required parts:
| Part | What it holds |
|---|---|
dataSources | DeltaTable sources: { name, type:"DeltaTable", properties:{ path: "abfss://…/Tables/<T>" } } |
graphDefinition | nodeTables + edgeTables mapping source columns → graph: propertyMappings, and on edges sourceNodeKeyColumns / destinationNodeKeyColumns; optional filter (Single/Group with and/or, operators Equal/Contains/GreaterThan/In…) |
graphType | nodeTypes (alias, labels[], primaryKeyProperties[], properties[]) + edgeTypes (alias, labels[], sourceNodeType.alias, destinationNodeType.alias, properties[]) |
stylingConfiguration | modelLayout: node positions, styles (size), pan, zoomLevel — visual only |
Note the indirection: the graphType declares abstract aliases (Customer_nodeType) and labels; the graphDefinition binds each alias to a dataSourceName and maps sourceColumn → propertyName. A composite key is expressed as multiple primaryKeyProperties and matching destinationNodeKeyColumns. Full JSON examples for all four parts → references/REFERENCE.md.
Data load & refresh
- Save = ingest. Selecting Save in the model editor both persists the model and reingests OneLake data to rebuild the queryable graph. To pull fresh data without model changes, just save again.
- Scheduled refresh: workspace → graph item → … → Schedule → Add schedule (minute/hourly/daily/weekly/monthly). Not available in My Workspace — shared workspaces only.
Other gotchas / limits
- Storage floor 100 GB provisioned (billed at OneLake Cache rate); compute billed by CPU uptime at 10 CU-seconds per second, rounded up to the minute. Uses your existing Fabric capacity — no separate SKU.
- Hard limits: max 10 graph models per workspace; the GA SKU processes roughly 2 billion graph elements (nodes + edges — contact the product team for larger); variable-length patterns support up to 8 hops; queries time out at 20 minutes and responses are truncated above 64 MB (aggregation gets unstable past 128 MB). String property max 65,535 chars;
List<T>property max 65,535 elements. See limitations. - NL2GQL (natural-language → GQL via Fabric Data Agent, see fabric-data-agent) is preview. openCypher support is preview and is the KQL-graph path, not this item.
- Set operations not yet supported.
UNION DISTINCT,EXCEPT,INTERSECT, andOTHERWISEare not available — compose with linear chaining of core statements (MATCH/LET/FILTER/RETURN) instead. Full conformance-gap list → limitations. - Governed by OneLake security + workspace RBAC (see fabric-security).
Reference
- MS Learn: Graph overview · How graph works · GQL language guide · GQL schema example · GQL conformance
- MS Learn: GQL Query API reference · Graph Model definition (REST) · Manage and refresh data
- Consolidated link bundle, full schema/JSON/value-encoding tables: references/REFERENCE.md
See also
- fabric-eventhouse — the other graph story: KQL
make-graph/graph-match/ openCypher in Eventhouse. Different engine; do not conflate. - fabric-tmdl-api — definition envelope, LRO polling, base64, "include all parts" rule (applies to GraphModel definitions too)
- fabric-rest-api — runtime item ID vs
.platformlogicalId, LRO 202 pattern, pagination - fabric-auth —
api.fabric.microsoft.comtoken audience for the query API - fabric-data-agent — graph as a Data Agent source for NL2GQL (preview)
- fabric-cli —
fabpath syntaxWorkspace.Workspace/Item.GraphModel, export/import