Dependencies
With resolve_dependencies=True, the default, plan_all_items() and
deploy_all_items() read what the selected items refer to, and deploy each
item after what it needs, even in a run that deploys only what changed.
References read
| Item | Needs | Read from |
|---|---|---|
| Report | SemanticModel | definition.pbir: the folder in datasetReference.byPath, or the initial catalog of byConnection |
| Notebook | Lakehouse | The default lakehouse: by logical ID, as Fabric writes a lakehouse of the same workspace, or else by default_lakehouse_name |
| Notebook | Environment | The attached environment, by logical ID |
| Notebook | Notebook | %run <notebook> (%run -b runs a script of the notebook's resources, not a notebook) |
A reference to something outside the source, such as a semantic model of another workspace, is left out: it is neither deployed nor blocking.
What the plan does with them
Say Orders.Notebook changed, and its default lakehouse is
Bronze.Lakehouse, which did not.
The workspace has the lakehouse: it is checked, not deployed.
NOOP Bronze.Lakehouse DEPENDENCY_REQUIRED: Required by Orders.Notebook (notebook default lakehouse); already in the workspace.
UPDATE Orders.Notebook SOURCE_CHANGED
The workspace lacks it, as when someone deleted it by hand: it is created first.
CREATE Bronze.Lakehouse DEPENDENCY_REQUIRED: Required by Orders.Notebook (notebook default lakehouse) and missing from the workspace.
UPDATE Orders.Notebook SOURCE_CHANGED
It cannot be created, because the run deploys only
item_types=["Notebook"] or because the source does not define it: the
notebook is blocked.
BLOCKED Orders.Notebook SOURCE_CHANGED: Needs Bronze.Lakehouse, which is missing from the workspace and not among the item types of this run.
An item is blocked too when a reference of its definition is broken, such
as a report whose byPath folder is missing or holds no semantic model, or
when it is part of a dependency cycle, such as two notebooks that %run
each other. What needs a blocked item is blocked in turn. A blocked item is
reported as failed, so the deployment state does not move.
Reports and their semantic model
In Git, a report's definition.pbir points to its semantic model by the
path of its folder (byPath). The Fabric API accepts no path: only a
connection to the model's ID in the workspace, which exists once the model
is deployed. So when it deploys such a report, the engine sends the
reference as a connection to the ID of that model in the target
workspace, the one created earlier in the same run or the one already
there. The file keeps its path.
In Git: "byPath": {"path": "../Sales.SemanticModel"}
Sent: "byConnection": {"connectionString": "semanticmodelid=<ID of Sales in the workspace>"}
A report whose model the workspace lacks fails with the reason, and nothing is sent. A report that already points to a model by connection is sent as it is.
When an item fails
The plan lists in each action's needs the items of the plan it needs.
When one of them fails to deploy, the item is not sent without it: it is
reported as skipped, and so is what needs a skipped item.
report = deploy_all_items("Sales-PRD", "stg/workspace", ...)
[(r.display_name, r.action, r.error) for r in report.results]
# [('Bronze', 'failed', 'Create failed with 400: ...'),
# ('Orders', 'skipped', 'Needs Bronze.Lakehouse, which failed.')]
The rest of the run goes on, and the deployment state does not move, so the next run tries both again.
Data pipelines
A data pipeline refers to notebooks, pipelines, dataflows and other items by ID, which only the workspace can resolve. After staging, every ID that points to the target workspace, nested activities included, is checked against it. An ID the workspace lacks, or a value that is no ID, such as a placeholder left unreplaced, gives a warning in the plan and in the log:
UPDATE Load.DataPipeline SOURCE_CHANGED: Warning: Activity 'Run Orders' refers to notebook '#{orders_notebook_id}#', which is not an ID (a placeholder left unreplaced?).
The pipeline is still deployed: an item created in the same run gets its ID only when it is created. References to other workspaces are not checked.
Deletions
The same references keep an item deleted from Git in the workspace while
an item that stays in the source refers to it, and so does the item's ID in
the workspace when another item's files hold it: see
Deletions. That check runs whatever resolve_dependencies
says.
Turning it off
resolve_dependencies=False deploys the selected items in DEPLOY_ORDER
without reading their references, as before: no item needs another, so a
failure skips nothing.
Reference
References between local items, read from their definitions.
LocalCatalog lists the items under a folder with the identity the
planner uses (item type and display name), their folder and their logical
ID. scan_references reads the definitions of the selected items, and of
the items they need, and turns each reference into a Dependency on a
local item, or into a broken reference when the definition points to a local
item that is not there. A reference to something outside the source, such as
a semantic model of another workspace, is left out: it is neither deployed
nor blocking.
References read:
- Report → SemanticModel:
datasetReferenceindefinition.pbir, by path, or by connection through theinitial catalogof the connection string. - Notebook → Lakehouse: the default lakehouse in the notebook metadata, by
logical ID (as Fabric writes it for a lakehouse of the same workspace) or
else by
default_lakehouse_name. - Notebook → Environment: the attached environment, by logical ID.
- Notebook → Notebook:
%run <notebook>;%run -bruns a script of the notebook's resources, not a notebook.
pipeline_references reads what a data pipeline refers to by ID
(notebooks, pipelines, dataflows, lakehouses and other items): those IDs
are the workspace's own, so they are checked against it rather than
resolved to local items.
CatalogItem
dataclass
A local item that references can point to.
Attributes:
| Name | Type | Description |
|---|---|---|
key |
ItemKey
|
Its item type, from the folder suffix, and its
display name, from |
path |
str
|
Its folder. |
logical_id |
str | None
|
|
Source code in src/pyfabricops/helpers/dependencies.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | |
IdReference
dataclass
A reference by ID from a data pipeline to an item of a workspace.
Attributes:
| Name | Type | Description |
|---|---|---|
kind |
str
|
What is referred to: |
item_id |
str
|
The ID, which may be a placeholder left unreplaced. |
workspace_id |
str | None
|
The workspace of the item, or None when the definition does not say, which means the pipeline's own. |
where |
str
|
Where the reference is, such as
|
Source code in src/pyfabricops/helpers/dependencies.py
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | |
LocalCatalog
The local items that references can point to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
items
|
Iterable[CatalogItem]
|
The items. When two share a type and display name, or a folder, the first one is kept. |
required |
Source code in src/pyfabricops/helpers/dependencies.py
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
__iter__()
Iterate over the items, one per type and display name.
Source code in src/pyfabricops/helpers/dependencies.py
128 129 130 | |
at(folder)
Return the item in a folder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder
|
str
|
The folder, in any form that points to it. |
required |
Returns:
| Type | Description |
|---|---|
CatalogItem | None
|
CatalogItem | None: The item, or None when there is none. |
Source code in src/pyfabricops/helpers/dependencies.py
144 145 146 147 148 149 150 151 152 153 154 | |
get(key)
Return the item with a type and display name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
ItemKey
|
The item type and display name. |
required |
Returns:
| Type | Description |
|---|---|
CatalogItem | None
|
CatalogItem | None: The item, or None when there is none. |
Source code in src/pyfabricops/helpers/dependencies.py
132 133 134 135 136 137 138 139 140 141 142 | |
read(path, item_types)
classmethod
List the items of the given types under a folder.
An item whose .platform cannot be read is left out; the planner
reports it when it is selected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
The folder of the items. |
required |
item_types
|
Sequence[str]
|
The item types to list. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
LocalCatalog |
LocalCatalog
|
The items found. |
Source code in src/pyfabricops/helpers/dependencies.py
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
with_logical_id(logical_id)
Return the item with a logical ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logical_id
|
str
|
The |
required |
Returns:
| Type | Description |
|---|---|
CatalogItem | None
|
CatalogItem | None: The item, or None when there is none. |
Source code in src/pyfabricops/helpers/dependencies.py
156 157 158 159 160 161 162 163 164 165 166 | |
ReferenceScan
dataclass
The references found from a selection of items.
Attributes:
| Name | Type | Description |
|---|---|---|
dependencies |
tuple[Dependency, ...]
|
The references to local items. |
broken |
Mapping[ItemKey, tuple[str, ...]]
|
For each item whose definition points to a local item that is not there, why. Read-only. |
Source code in src/pyfabricops/helpers/dependencies.py
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | |
pipeline_references(folder)
Read what a data pipeline refers to by ID.
Every activity is read, those nested in ForEach, If Condition, Switch and Until included.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder
|
str
|
The folder of the pipeline, with its
|
required |
Returns:
| Type | Description |
|---|---|
tuple[IdReference, ...]
|
tuple[IdReference, ...]: The references, each once, in the order found; none when the content cannot be read. |
Source code in src/pyfabricops/helpers/dependencies.py
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | |
scan_references(catalog, keys)
Read the references of the given items and of every item they need.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
catalog
|
LocalCatalog
|
The local items. |
required |
keys
|
Iterable[ItemKey]
|
The items to start from. An item not in the catalog, or of a type whose references are not read, gives none. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ReferenceScan |
ReferenceScan
|
What the items refer to. |
Source code in src/pyfabricops/helpers/dependencies.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | |
Dependency graph: which local items need which, and in what order.
An item depends on another when its definition refers to it, such as a
report on its semantic model. DependencyGraph holds those references
between items of the source and answers three questions for the planner:
what the selected items need (required_by), in which order to deploy
items so that each comes after what it needs (order), and which items
need one another (cycles). Like the planner, it calls no Fabric API and
reads no file: finding the references is the engine's job.
ItemKey = tuple[str, str]
module-attribute
An item, as (item_type, display_name).
Dependency
dataclass
A reference from one local item to another.
Attributes:
| Name | Type | Description |
|---|---|---|
source |
ItemKey
|
The item whose definition holds the reference. |
target |
ItemKey
|
The item it refers to, needed first. |
via |
str
|
Where the reference is, such as |
Source code in src/pyfabricops/helpers/dependency_graph.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
DependencyGraph
The references between local items.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dependencies
|
Iterable[Dependency]
|
The references found in the source; a repeated one counts once. Defaults to none. |
()
|
Examples:
report, model = ("Report", "Sales"), ("SemanticModel", "Sales")
graph = DependencyGraph([Dependency(report, model, "definition.pbir")])
graph.order([report, model]) # (model, report)
Source code in src/pyfabricops/helpers/dependency_graph.py
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
cycles(keys)
Return the groups of items that need one another.
Only references between the given items count; an item that refers to itself is a group on its own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
Sequence[ItemKey]
|
The items to check. |
required |
Returns:
| Type | Description |
|---|---|
tuple[tuple[ItemKey, ...], ...]
|
tuple[tuple[ItemKey, ...], ...]: Each group in the order given, the groups in the order of their first item. |
Source code in src/pyfabricops/helpers/dependency_graph.py
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | |
dependencies_of(key)
Return the references an item holds, in the order they were found.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
ItemKey
|
The item. |
required |
Returns:
| Type | Description |
|---|---|
tuple[Dependency, ...]
|
tuple[Dependency, ...]: Its references, possibly none. |
Source code in src/pyfabricops/helpers/dependency_graph.py
66 67 68 69 70 71 72 73 74 75 76 | |
order(keys)
Order items so that each comes after the items it needs.
Only references between the given items count. Each item keeps its place in the order given, preceded by the items it needs that have not come yet, so a caller that sorts items by type and path first keeps that order wherever nothing else is needed. Items that need one another stay together, in the order given, after what they need.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
Sequence[ItemKey]
|
The items, in their default order. |
required |
Returns:
| Type | Description |
|---|---|
tuple[ItemKey, ...]
|
tuple[ItemKey, ...]: The same items, each after the ones it needs. |
Source code in src/pyfabricops/helpers/dependency_graph.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | |
required_by(keys)
Return every item the given ones need, directly or through others.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
Iterable[ItemKey]
|
The items to start from. |
required |
Returns:
| Type | Description |
|---|---|
tuple[ItemKey, ...]
|
tuple[ItemKey, ...]: The items they need, without the given ones, nearest first. |
Source code in src/pyfabricops/helpers/dependency_graph.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | |