datajunction 0.0.154__tar.gz → 0.0.155__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. {datajunction-0.0.154 → datajunction-0.0.155}/PKG-INFO +1 -1
  2. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/__about__.py +1 -1
  3. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/cli.py +22 -12
  4. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/deployment.py +32 -4
  5. datajunction-0.0.154/datajunction/seed/nodes/date.dimension.yaml → datajunction-0.0.155/datajunction/seed/nodes/date.yaml +2 -0
  6. datajunction-0.0.155/datajunction/seed/nodes/deployment.yaml +89 -0
  7. datajunction-0.0.154/datajunction/seed/nodes/dimension_link.dimension.yaml → datajunction-0.0.155/datajunction/seed/nodes/dimension_link.yaml +12 -1
  8. datajunction-0.0.155/datajunction/seed/nodes/distinct_node_authors.yaml +20 -0
  9. datajunction-0.0.155/datajunction/seed/nodes/distinct_node_editors.yaml +20 -0
  10. datajunction-0.0.155/datajunction/seed/nodes/dj.yaml +33 -0
  11. datajunction-0.0.154/datajunction/seed/nodes/is_active.dimension.yaml → datajunction-0.0.155/datajunction/seed/nodes/is_active.yaml +6 -1
  12. datajunction-0.0.154/datajunction/seed/nodes/materialization.dimension.yaml → datajunction-0.0.155/datajunction/seed/nodes/materialization.yaml +21 -1
  13. datajunction-0.0.155/datajunction/seed/nodes/median_deployment_duration_seconds.yaml +23 -0
  14. datajunction-0.0.155/datajunction/seed/nodes/median_dim_links_per_node.yaml +26 -0
  15. datajunction-0.0.155/datajunction/seed/nodes/median_dimension_indegree.yaml +23 -0
  16. datajunction-0.0.155/datajunction/seed/nodes/median_downstream_count.yaml +22 -0
  17. datajunction-0.0.155/datajunction/seed/nodes/median_revisions_per_node.yaml +21 -0
  18. datajunction-0.0.155/datajunction/seed/nodes/median_upstream_count.yaml +22 -0
  19. datajunction-0.0.155/datajunction/seed/nodes/namespace.yaml +148 -0
  20. datajunction-0.0.155/datajunction/seed/nodes/node_revision.yaml +60 -0
  21. datajunction-0.0.154/datajunction/seed/nodes/node_type.dimension.yaml → datajunction-0.0.155/datajunction/seed/nodes/node_type.yaml +6 -1
  22. datajunction-0.0.155/datajunction/seed/nodes/nodes.yaml +232 -0
  23. datajunction-0.0.155/datajunction/seed/nodes/number_of_branches.yaml +24 -0
  24. datajunction-0.0.155/datajunction/seed/nodes/number_of_deployments.yaml +19 -0
  25. datajunction-0.0.155/datajunction/seed/nodes/number_of_materializations.yaml +23 -0
  26. datajunction-0.0.155/datajunction/seed/nodes/number_of_namespaces.yaml +19 -0
  27. datajunction-0.0.155/datajunction/seed/nodes/number_of_nodes.yaml +23 -0
  28. datajunction-0.0.155/datajunction/seed/nodes/number_of_orphan_nodes.yaml +23 -0
  29. datajunction-0.0.155/datajunction/seed/nodes/number_of_unused_dimensions.yaml +21 -0
  30. datajunction-0.0.155/datajunction/seed/nodes/repo.yaml +64 -0
  31. datajunction-0.0.154/datajunction/seed/nodes/user.dimension.yaml → datajunction-0.0.155/datajunction/seed/nodes/user.yaml +6 -1
  32. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_builder.py +1 -0
  33. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_cli.py +17 -4
  34. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_deploy.py +25 -0
  35. datajunction-0.0.154/datajunction/seed/nodes/dj.yaml +0 -15
  36. datajunction-0.0.154/datajunction/seed/nodes/node_without_description.metric.yaml +0 -18
  37. datajunction-0.0.154/datajunction/seed/nodes/nodes.dimension.yaml +0 -41
  38. datajunction-0.0.154/datajunction/seed/nodes/number_of_materializations.metric.yaml +0 -12
  39. datajunction-0.0.154/datajunction/seed/nodes/number_of_nodes.metric.yaml +0 -12
  40. {datajunction-0.0.154 → datajunction-0.0.155}/.coveragerc +0 -0
  41. {datajunction-0.0.154 → datajunction-0.0.155}/.gitignore +0 -0
  42. {datajunction-0.0.154 → datajunction-0.0.155}/.pre-commit-config.yaml +0 -0
  43. {datajunction-0.0.154 → datajunction-0.0.155}/LICENSE.txt +0 -0
  44. {datajunction-0.0.154 → datajunction-0.0.155}/Makefile +0 -0
  45. {datajunction-0.0.154 → datajunction-0.0.155}/README.md +0 -0
  46. {datajunction-0.0.154 → datajunction-0.0.155}/claude_desktop_config.example.json +0 -0
  47. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/__init__.py +0 -0
  48. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/_base.py +0 -0
  49. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/_internal.py +0 -0
  50. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/admin.py +0 -0
  51. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/builder.py +0 -0
  52. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/client.py +0 -0
  53. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/compile.py +0 -0
  54. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/exceptions.py +0 -0
  55. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/mcp/__init__.py +0 -0
  56. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/mcp/cli.py +0 -0
  57. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/mcp/config.py +0 -0
  58. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/models.py +0 -0
  59. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/nodes.py +0 -0
  60. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/rendering.py +0 -0
  61. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/seed/init_system_nodes.py +0 -0
  62. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/skills/datajunction.md +0 -0
  63. {datajunction-0.0.154 → datajunction-0.0.155}/datajunction/tags.py +0 -0
  64. {datajunction-0.0.154 → datajunction-0.0.155}/pyproject.toml +0 -0
  65. {datajunction-0.0.154 → datajunction-0.0.155}/setup.cfg +0 -0
  66. {datajunction-0.0.154 → datajunction-0.0.155}/tests/__init__.py +0 -0
  67. {datajunction-0.0.154 → datajunction-0.0.155}/tests/conftest.py +0 -0
  68. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/deploy0/dj.yaml +0 -0
  69. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/deploy0/roads/companies.yaml +0 -0
  70. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/deploy0/roads/companies_dim.yaml +0 -0
  71. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/deploy0/roads/contractor.yaml +0 -0
  72. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/deploy0/roads/contractors.yaml +0 -0
  73. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/deploy0/roads/us_state.yaml +0 -0
  74. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/deploy0/roads/us_states.yaml +0 -0
  75. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/dj.yaml +0 -0
  76. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/avg_length_of_employment.metric.yaml +0 -0
  77. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/avg_repair_price.metric.yaml +0 -0
  78. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/avg_time_to_dispatch.metric.yaml +0 -0
  79. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/contractor.dimension.yaml +0 -0
  80. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/contractors.source.yaml +0 -0
  81. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/date.source.yaml +0 -0
  82. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/date_dim.dimension.yaml +0 -0
  83. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/dispatcher.dimension.yaml +0 -0
  84. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/dispatchers.source.yaml +0 -0
  85. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/hard_hat.dimension.yaml +0 -0
  86. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/hard_hat_state.source.yaml +0 -0
  87. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/hard_hats.source.yaml +0 -0
  88. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/local_hard_hats.dimension.yaml +0 -0
  89. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/municipality.source.yaml +0 -0
  90. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/municipality_dim.dimension.yaml +0 -0
  91. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/municipality_municipality_type.source.yaml +0 -0
  92. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/municipality_type.source.yaml +0 -0
  93. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/national_level_agg.transform.yaml +0 -0
  94. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/num_repair_orders.metric.yaml +0 -0
  95. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/regional_level_agg.transform.yaml +0 -0
  96. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/regional_repair_efficiency.metric.yaml +0 -0
  97. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/repair_order.dimension.yaml +0 -0
  98. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/repair_order_details.source.yaml +0 -0
  99. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/repair_order_transform.transform.yaml +0 -0
  100. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/repair_orders.source.yaml +0 -0
  101. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/repair_orders_cube.cube.yaml +0 -0
  102. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/repair_type.source.yaml +0 -0
  103. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/total_repair_cost.metric.yaml +0 -0
  104. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/total_repair_order_discounts.metric.yaml +0 -0
  105. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/us_region.source.yaml +0 -0
  106. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/us_state.dimension.yaml +0 -0
  107. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project1/roads/us_states.source.yaml +0 -0
  108. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project10/dj.yaml +0 -0
  109. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/avg_length_of_employment.metric.yaml +0 -0
  110. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/avg_repair_price.metric.yaml +0 -0
  111. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/avg_time_to_dispatch.metric.yaml +0 -0
  112. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/contractor.dimension.yaml +0 -0
  113. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/contractors.source.yaml +0 -0
  114. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/date.source.yaml +0 -0
  115. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/date_dim.dimension.yaml +0 -0
  116. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/dispatcher.dimension.yaml +0 -0
  117. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/dispatchers.source.yaml +0 -0
  118. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/dj.yaml +0 -0
  119. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/hard_hat.dimension.yaml +0 -0
  120. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/hard_hat_state.source.yaml +0 -0
  121. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/hard_hats.source.yaml +0 -0
  122. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/local_hard_hats.dimension.yaml +0 -0
  123. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/municipality.source.yaml +0 -0
  124. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/municipality_dim.dimension.yaml +0 -0
  125. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/municipality_municipality_type.source.yaml +0 -0
  126. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/municipality_type.source.yaml +0 -0
  127. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/national_level_agg.transform.yaml +0 -0
  128. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/num_repair_orders.metric.yaml +0 -0
  129. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/regional_level_agg.transform.yaml +0 -0
  130. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/regional_repair_efficiency.metric.yaml +0 -0
  131. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/repair_order.dimension.yaml +0 -0
  132. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/repair_order_details.source.yaml +0 -0
  133. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/repair_order_transform.transform.yaml +0 -0
  134. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/repair_orders.source.yaml +0 -0
  135. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/repair_orders_cube.cube.yaml +0 -0
  136. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/repair_type.source.yaml +0 -0
  137. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/total_repair_cost.metric.yaml +0 -0
  138. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/total_repair_order_discounts.metric.yaml +0 -0
  139. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/us_region.source.yaml +0 -0
  140. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/us_state.dimension.yaml +0 -0
  141. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project11/us_states.source.yaml +0 -0
  142. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project12/dj.yaml +0 -0
  143. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project12/roads/companies.source.yaml +0 -0
  144. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project12/roads/companies_dim.dimension.yaml +0 -0
  145. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project12/roads/contractor.dimension.yaml +0 -0
  146. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project12/roads/contractors.source.yaml +0 -0
  147. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project12/roads/us_state.dimension.yaml +0 -0
  148. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project12/roads/us_states.source.yaml +0 -0
  149. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project2/dj.yaml +0 -0
  150. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project2/some_node.source.yaml +0 -0
  151. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project3/dj.yaml +0 -0
  152. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project3/some_node.yaml +0 -0
  153. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project4/dj.yaml +0 -0
  154. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project4/very/very/deeply/nested/namespace/some_node.source.yaml +0 -0
  155. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project5/dj.yaml +0 -0
  156. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project5/some_node.a.b.c.source.yaml +0 -0
  157. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project6/dj.yaml +0 -0
  158. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project6/roads/contractor.dimension.yaml +0 -0
  159. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project6/roads/contractors.source.yaml +0 -0
  160. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project7/dj.yaml +0 -0
  161. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project7/roads/contractor.dimension.yaml +0 -0
  162. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project7/roads/contractors.source.yaml +0 -0
  163. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project8/dj.yaml +0 -0
  164. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project9/dj.yaml +0 -0
  165. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project9/roads/companies.source.yaml +0 -0
  166. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project9/roads/companies_dim.dimension.yaml +0 -0
  167. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project9/roads/contractor.dimension.yaml +0 -0
  168. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project9/roads/contractors.source.yaml +0 -0
  169. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project9/roads/us_state.dimension.yaml +0 -0
  170. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples/project9/roads/us_states.source.yaml +0 -0
  171. {datajunction-0.0.154 → datajunction-0.0.155}/tests/examples.py +0 -0
  172. {datajunction-0.0.154 → datajunction-0.0.155}/tests/mcp/README.md +0 -0
  173. {datajunction-0.0.154 → datajunction-0.0.155}/tests/mcp/__init__.py +0 -0
  174. {datajunction-0.0.154 → datajunction-0.0.155}/tests/mcp/test_cli.py +0 -0
  175. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test__internal.py +0 -0
  176. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_admin.py +0 -0
  177. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_base.py +0 -0
  178. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_client.py +0 -0
  179. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_compile.py +0 -0
  180. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_generated_client.py +0 -0
  181. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_integration.py +0 -0
  182. {datajunction-0.0.154 → datajunction-0.0.155}/tests/test_models.py +0 -0
  183. {datajunction-0.0.154 → datajunction-0.0.155}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datajunction
3
- Version: 0.0.154
3
+ Version: 0.0.155
4
4
  Summary: DataJunction client library for connecting to a DataJunction server
5
5
  Project-URL: repository, https://github.com/DataJunction/dj
6
6
  Author-email: DataJunction Authors <yian.shang@gmail.com>
@@ -2,4 +2,4 @@
2
2
  Version for Hatch
3
3
  """
4
4
 
5
- __version__ = "0.0.154"
5
+ __version__ = "0.0.155"
@@ -14,7 +14,7 @@ from rich.syntax import Syntax
14
14
  from rich.table import Table
15
15
  from rich.text import Text
16
16
 
17
- from datajunction import DJBuilder, Project
17
+ from datajunction import DJBuilder
18
18
  from datajunction.deployment import DeploymentService
19
19
  from datajunction.exceptions import DJClientException, DJDeploymentFailure
20
20
 
@@ -1846,6 +1846,7 @@ model: inherit
1846
1846
  """
1847
1847
  tables = [
1848
1848
  "node",
1849
+ "nodenamespace",
1849
1850
  "noderevision",
1850
1851
  "users",
1851
1852
  "materialization",
@@ -1854,6 +1855,7 @@ model: inherit
1854
1855
  "backfill",
1855
1856
  "collection",
1856
1857
  "dimensionlink",
1858
+ "deployments",
1857
1859
  ]
1858
1860
  for table in tables:
1859
1861
  try:
@@ -1869,19 +1871,27 @@ model: inherit
1869
1871
  )
1870
1872
  logger.info("Finished registering DJ system metadata tables")
1871
1873
 
1872
- logger.info("Loading DJ system nodes...")
1874
+ logger.info("Pushing DJ system nodes...")
1873
1875
  script_dir = Path(__file__).resolve().parent
1874
1876
  project_dir = script_dir / "seed" / type
1875
- project = Project.load(str(project_dir))
1876
- logger.info("Finished loading DJ system nodes.")
1877
-
1878
- logger.info("Compiling DJ system nodes...")
1879
- compiled_project = project.compile()
1880
- logger.info("Finished compiling DJ system nodes.")
1881
-
1882
- logger.info("Deploying DJ system nodes...")
1883
- compiled_project.deploy(client=self.builder_client)
1884
- logger.info("Finished deploying DJ system nodes.")
1877
+ # Read the project's declared prefix and pass it explicitly so the
1878
+ # push flow doesn't apply git-branch namespace derivation to the
1879
+ # bootstrap nodes (they always belong to the canonical system namespace).
1880
+ project_yaml_path = project_dir / "dj.yaml"
1881
+ project_meta: dict = {}
1882
+ if project_yaml_path.exists(): # pragma: no branch
1883
+ import yaml as _yaml
1884
+
1885
+ with open(project_yaml_path, encoding="utf-8") as fh:
1886
+ project_meta = _yaml.safe_load(fh) or {}
1887
+ system_namespace = project_meta.get("namespace") or project_meta.get(
1888
+ "prefix",
1889
+ )
1890
+ self.deployment_service.push(
1891
+ str(project_dir),
1892
+ namespace=system_namespace,
1893
+ )
1894
+ logger.info("Finished pushing DJ system nodes.")
1885
1895
 
1886
1896
 
1887
1897
  def main(builder_client: DJBuilder | None = None):
@@ -136,9 +136,15 @@ class DeploymentService:
136
136
  branch=source.get("branch") or branch,
137
137
  )
138
138
 
139
- if branch:
140
- # Use base_namespace from dj.yaml as parent, whether --namespace was
141
- # passed explicitly or derived automatically
139
+ # Apply git config in the normal push flow. Skip only when the
140
+ # caller passed an explicit ``namespace`` equal to the project's
141
+ # base namespace that's the bootstrap / system-seed case where
142
+ # we'd otherwise set parent to the same namespace and error with
143
+ # "a namespace cannot be its own parent".
144
+ skip_git_config = (
145
+ namespace is not None and deployment_spec["namespace"] == base_namespace
146
+ )
147
+ if branch and not skip_git_config:
142
148
  parent_namespace = base_namespace or None
143
149
  try:
144
150
  self.client._set_namespace_git_config(
@@ -389,10 +395,30 @@ class DeploymentService:
389
395
  nodes = []
390
396
  warnings = []
391
397
  nodes_dir = Path(base_dir)
398
+ # Skip dirs that may carry stray YAMLs but aren't part of the project
399
+ # (vendored deps, build artifacts, dot-dirs).
400
+ skip_dir_names = {
401
+ "venv",
402
+ ".venv",
403
+ "node_modules",
404
+ "site-packages",
405
+ "__pycache__",
406
+ ".git",
407
+ "build",
408
+ "dist",
409
+ ".tox",
410
+ }
392
411
  for path in nodes_dir.rglob("*.yaml"):
393
412
  if path.name == "dj.yaml":
394
413
  continue
414
+ parents = path.relative_to(nodes_dir).parts[:-1]
415
+ if any(part in skip_dir_names or part.startswith(".") for part in parents):
416
+ continue
395
417
  node_dict = DeploymentService.read_yaml_file(path)
418
+ if not isinstance(node_dict, dict):
419
+ # Not a node definition — stray YAML (e.g. a list-typed file
420
+ # from a vendored package); skip rather than crash.
421
+ continue
396
422
 
397
423
  # Check filename matches node name
398
424
  node_name = node_dict.get("name", "")
@@ -439,8 +465,10 @@ class DeploymentService:
439
465
  seen_names[node_name] = node
440
466
  nodes = list(seen_names.values())
441
467
 
468
+ # Accept either `namespace:` (new) or `prefix:` (legacy seed format) in dj.yaml
442
469
  deployment_spec = {
443
- "namespace": project_metadata.get("namespace", ""), # fallback to empty
470
+ "namespace": project_metadata.get("namespace")
471
+ or project_metadata.get("prefix", ""),
444
472
  "nodes": nodes,
445
473
  "tags": project_metadata.get("tags", []),
446
474
  }
@@ -1,3 +1,5 @@
1
+ name: ${prefix}date
2
+ node_type: dimension
1
3
  display_name: Date
2
4
  description: ''
3
5
  query: 'SELECT 1 AS dateint '
@@ -0,0 +1,89 @@
1
+ name: ${prefix}deployment
2
+ node_type: dimension
3
+ display_name: Deployment
4
+ description: |-
5
+ One row per deployment. Repo / branch / git-config attributes are extracted
6
+ inline from the deployment's ``spec`` JSON, so the dim can be sliced by
7
+ source type, repository, branch, CI system, etc. without a Postgres view.
8
+ query: |-
9
+ SELECT
10
+ D.uuid,
11
+ D.namespace,
12
+ CAST(D.status AS STRING) AS status,
13
+ D.created_by_id,
14
+ D.created_at,
15
+ D.updated_at,
16
+ CAST(TO_CHAR(CAST(D.created_at AS date), 'YYYYMMDD') AS integer) AS created_at_date,
17
+ CAST(TO_CHAR(CAST(DATE_TRUNC('week', D.created_at) AS date), 'YYYYMMDD') AS integer) AS created_at_week,
18
+ CAST(TO_CHAR(CAST(D.updated_at AS date), 'YYYYMMDD') AS integer) AS updated_at_date,
19
+ CAST(TO_CHAR(CAST(DATE_TRUNC('week', D.updated_at) AS date), 'YYYYMMDD') AS integer) AS updated_at_week,
20
+ CAST(json_extract_path_text(D.spec, 'source', 'type') AS STRING) AS source_type,
21
+ CAST(json_extract_path_text(D.spec, 'source', 'repository') AS STRING) AS repository,
22
+ CAST(json_extract_path_text(D.spec, 'source', 'branch') AS STRING) AS branch,
23
+ CAST(json_extract_path_text(D.spec, 'source', 'commit_sha') AS STRING) AS commit_sha,
24
+ CAST(json_extract_path_text(D.spec, 'source', 'ci_system') AS STRING) AS ci_system,
25
+ CAST(EXTRACT(EPOCH FROM (D.updated_at - D.created_at)) AS double) AS duration_seconds
26
+ FROM source.dj_metadata.public.deployments D
27
+ columns:
28
+ - name: uuid
29
+ attributes:
30
+ - hidden
31
+ - name: created_by_id
32
+ attributes:
33
+ - hidden
34
+ - name: created_at
35
+ attributes:
36
+ - hidden
37
+ - name: updated_at
38
+ attributes:
39
+ - hidden
40
+ - name: namespace
41
+ display_name: Namespace
42
+ - name: status
43
+ display_name: Status
44
+ - name: source_type
45
+ display_name: Source Type
46
+ - name: repository
47
+ display_name: Repository
48
+ - name: branch
49
+ display_name: Branch
50
+ - name: commit_sha
51
+ display_name: Commit SHA
52
+ attributes:
53
+ - hidden
54
+ - name: ci_system
55
+ display_name: CI System
56
+ - name: duration_seconds
57
+ display_name: Duration (seconds)
58
+ attributes:
59
+ - hidden
60
+ - name: created_at_date
61
+ display_name: Created At (Day)
62
+ - name: created_at_week
63
+ display_name: Created At (Week)
64
+ - name: updated_at_date
65
+ display_name: Updated At (Day)
66
+ - name: updated_at_week
67
+ display_name: Updated At (Week)
68
+ primary_key:
69
+ - uuid
70
+ dimension_links:
71
+ - type: join
72
+ dimension_node: ${prefix}user
73
+ join_type: left
74
+ join_on: ${prefix}deployment.created_by_id = ${prefix}user.id
75
+ - type: join
76
+ dimension_node: ${prefix}date
77
+ join_type: left
78
+ join_on: ${prefix}deployment.created_at_date = ${prefix}date.dateint
79
+ role: created_at
80
+ - type: join
81
+ dimension_node: ${prefix}date
82
+ join_type: left
83
+ join_on: ${prefix}deployment.updated_at_date = ${prefix}date.dateint
84
+ role: updated_at
85
+ - type: join
86
+ dimension_node: ${prefix}namespace
87
+ join_type: left
88
+ join_on: ${prefix}deployment.namespace = ${prefix}namespace.name
89
+ tags: []
@@ -1,3 +1,5 @@
1
+ name: ${prefix}dimension_link
2
+ node_type: dimension
1
3
  display_name: Dimension Link
2
4
  description: ''
3
5
  query: |-
@@ -6,7 +8,16 @@ query: |-
6
8
  dimension_id,
7
9
  node_revision_id
8
10
  FROM source.dj_metadata.public.dimensionlink
9
- columns: []
11
+ columns:
12
+ - name: id
13
+ attributes:
14
+ - hidden
15
+ - name: dimension_id
16
+ attributes:
17
+ - hidden
18
+ - name: node_revision_id
19
+ attributes:
20
+ - hidden
10
21
  primary_key:
11
22
  - id
12
23
  dimension_links:
@@ -0,0 +1,20 @@
1
+ name: ${prefix}distinct_node_authors
2
+ node_type: metric
3
+ display_name: Distinct Node Authors
4
+ description: |-
5
+ Count of distinct users who originally created nodes. When sliced by
6
+ ``created_at_day`` / ``created_at_week`` etc., gives daily / weekly /
7
+ monthly active authors.
8
+ query: |-
9
+ SELECT COUNT(DISTINCT created_by_id)
10
+ FROM ${prefix}nodes
11
+ tags: []
12
+ custom_metadata:
13
+ group: Activity
14
+ subgroup: Authors & Edits
15
+ required_dimensions: []
16
+ direction: null
17
+ unit: null
18
+ significant_digits: null
19
+ min_decimal_exponent: null
20
+ max_decimal_exponent: null
@@ -0,0 +1,20 @@
1
+ name: ${prefix}distinct_node_editors
2
+ node_type: metric
3
+ display_name: Distinct Node Editors
4
+ description: |-
5
+ Count of distinct users who authored a node revision. Slice by
6
+ ``created_at_day`` / ``created_at_week`` to get daily / weekly / monthly
7
+ active editors (people iterating on nodes, not just first-time creators).
8
+ query: |-
9
+ SELECT COUNT(DISTINCT created_by_id)
10
+ FROM ${prefix}node_revision
11
+ tags: []
12
+ custom_metadata:
13
+ group: Activity
14
+ subgroup: Authors & Edits
15
+ required_dimensions: []
16
+ direction: null
17
+ unit: null
18
+ significant_digits: null
19
+ min_decimal_exponent: null
20
+ max_decimal_exponent: null
@@ -0,0 +1,33 @@
1
+ name: DJ System Metadata
2
+ description: This project contains DJ system metadata modeled in DJ itself.
3
+ prefix: system.dj
4
+ build:
5
+ priority:
6
+ # Dimension nodes (sources of breakdowns)
7
+ - repo
8
+ - namespace
9
+ - nodes
10
+ - node_revision
11
+ - dimension_link
12
+ - materialization
13
+ - deployment
14
+ - node_type
15
+ - is_active
16
+ - user
17
+ - date
18
+ # Metric nodes
19
+ - number_of_nodes
20
+ - number_of_namespaces
21
+ - number_of_materializations
22
+ - number_of_deployments
23
+ - median_deployment_duration_seconds
24
+ - distinct_node_authors
25
+ - distinct_node_editors
26
+ - median_revisions_per_node
27
+ - median_upstream_count
28
+ - median_downstream_count
29
+ - median_dim_links_per_node
30
+ - median_dimension_indegree
31
+ - number_of_orphan_nodes
32
+ - number_of_unused_dimensions
33
+ - number_of_branches
@@ -1,3 +1,5 @@
1
+ name: ${prefix}is_active
2
+ node_type: dimension
1
3
  display_name: Is Active
2
4
  description: ''
3
5
  query: |-
@@ -8,7 +10,10 @@ query: |-
8
10
  (true, 'Active'),
9
11
  (false, 'Deactivated')
10
12
  AS t (active_id, active_status);
11
- columns: []
13
+ columns:
14
+ - name: active_id
15
+ attributes:
16
+ - hidden
12
17
  primary_key:
13
18
  - active_id
14
19
  dimension_links: []
@@ -1,3 +1,5 @@
1
+ name: ${prefix}materialization
2
+ node_type: dimension
1
3
  display_name: Materialization
2
4
  description: ''
3
5
  query: |-
@@ -9,7 +11,25 @@ query: |-
9
11
  M.strategy,
10
12
  M.schedule
11
13
  FROM source.dj_metadata.public.materialization M
12
- columns: []
14
+ columns:
15
+ - name: id
16
+ attributes:
17
+ - hidden
18
+ - name: node_revision_id
19
+ attributes:
20
+ - hidden
21
+ - name: name
22
+ display_name: Materialization Name
23
+ attributes:
24
+ - hidden
25
+ - name: job
26
+ display_name: Orchestrator Job
27
+ attributes:
28
+ - hidden
29
+ - name: strategy
30
+ display_name: Strategy
31
+ - name: schedule
32
+ display_name: Schedule
13
33
  primary_key:
14
34
  - id
15
35
  dimension_links:
@@ -0,0 +1,23 @@
1
+ name: ${prefix}median_deployment_duration_seconds
2
+ node_type: metric
3
+ display_name: Median Deployment Duration (seconds)
4
+ description: |-
5
+ Median elapsed time from ``created_at`` to ``updated_at`` per deployment.
6
+ Slice by ``deployment.status`` to compare successful vs failed deploys,
7
+ by ``deployment.source_type`` to compare git vs local, or by
8
+ ``deployment.created_at_week`` to trend over time.
9
+ query: |-
10
+ SELECT MEDIAN(duration_seconds)
11
+ FROM ${prefix}deployment
12
+ tags: []
13
+ custom_metadata:
14
+ group: Activity
15
+ subgroup: Deployments
16
+ suggested_compare_by:
17
+ - system.dj.deployment.status
18
+ required_dimensions: []
19
+ direction: lower_is_better
20
+ unit: null
21
+ significant_digits: 2
22
+ min_decimal_exponent: null
23
+ max_decimal_exponent: null
@@ -0,0 +1,26 @@
1
+ name: ${prefix}median_dim_links_per_node
2
+ node_type: metric
3
+ display_name: Median Dimension Links per Linkable Node
4
+ description: |-
5
+ Median number of dimension links defined on each node's current revision,
6
+ restricted to nodes that *can* define links (transforms and dimensions —
7
+ sources, metrics, and cubes inherit their dim links through their parents,
8
+ so including them would just dilute the median with zeros).
9
+
10
+ Slice by ``nodes.type`` to compare transforms vs dimensions, or by
11
+ ``namespace.top_level`` to see which areas have richer dim graphs.
12
+ query: |-
13
+ SELECT MEDIAN(IF(type IN ('TRANSFORM', 'DIMENSION'), dim_link_count, NULL))
14
+ FROM ${prefix}nodes
15
+ tags: []
16
+ custom_metadata:
17
+ group: Quality
18
+ subgroup: Lineage Shape
19
+ suggested_compare_by:
20
+ - system.dj.node_type.type
21
+ required_dimensions: []
22
+ direction: null
23
+ unit: null
24
+ significant_digits: 2
25
+ min_decimal_exponent: null
26
+ max_decimal_exponent: null
@@ -0,0 +1,23 @@
1
+ name: ${prefix}median_dimension_indegree
2
+ node_type: metric
3
+ display_name: Median Dimension Indegree
4
+ description: |-
5
+ Median number of distinct upstream nodes that link TO each dimension node
6
+ via their current revision. Higher = more reused dimensions. Computed only
7
+ over dimension nodes — non-dimension types are excluded so they don't
8
+ drag the median to zero.
9
+ query: |-
10
+ SELECT MEDIAN(IF(type = 'DIMENSION', dim_indegree, NULL))
11
+ FROM ${prefix}nodes
12
+ tags: []
13
+ custom_metadata:
14
+ group: Quality
15
+ subgroup: Lineage Shape
16
+ suggested_compare_by:
17
+ - system.dj.namespace.top_level
18
+ required_dimensions: []
19
+ direction: higher_is_better
20
+ unit: null
21
+ significant_digits: 2
22
+ min_decimal_exponent: null
23
+ max_decimal_exponent: null
@@ -0,0 +1,22 @@
1
+ name: ${prefix}median_downstream_count
2
+ node_type: metric
3
+ display_name: Median Downstream Count
4
+ description: |-
5
+ Median number of distinct downstream nodes per node (current revisions only).
6
+ Useful for understanding fanout — high values mean many consumers depend on
7
+ the typical node.
8
+ query: |-
9
+ SELECT MEDIAN(child_count)
10
+ FROM ${prefix}nodes
11
+ tags: []
12
+ custom_metadata:
13
+ group: Quality
14
+ subgroup: Lineage Shape
15
+ suggested_compare_by:
16
+ - system.dj.node_type.type
17
+ required_dimensions: []
18
+ direction: null
19
+ unit: null
20
+ significant_digits: 2
21
+ min_decimal_exponent: null
22
+ max_decimal_exponent: null
@@ -0,0 +1,21 @@
1
+ name: ${prefix}median_revisions_per_node
2
+ node_type: metric
3
+ display_name: Median Revisions per Node
4
+ description: |-
5
+ Median number of revisions across nodes. Slice by ``nodes.type`` to see
6
+ which entity types churn the most.
7
+ query: |-
8
+ SELECT MEDIAN(revision_count)
9
+ FROM ${prefix}nodes
10
+ tags: []
11
+ custom_metadata:
12
+ group: Quality
13
+ subgroup: Lineage Shape
14
+ suggested_compare_by:
15
+ - system.dj.node_type.type
16
+ required_dimensions: []
17
+ direction: null
18
+ unit: null
19
+ significant_digits: 2
20
+ min_decimal_exponent: null
21
+ max_decimal_exponent: null
@@ -0,0 +1,22 @@
1
+ name: ${prefix}median_upstream_count
2
+ node_type: metric
3
+ display_name: Median Upstream Count
4
+ description: |-
5
+ Median number of direct upstream parents across nodes (current revisions
6
+ only). Sliced by ``nodes.type``, surfaces how interconnected each entity
7
+ type tends to be.
8
+ query: |-
9
+ SELECT MEDIAN(parent_count)
10
+ FROM ${prefix}nodes
11
+ tags: []
12
+ custom_metadata:
13
+ group: Quality
14
+ subgroup: Lineage Shape
15
+ suggested_compare_by:
16
+ - system.dj.node_type.type
17
+ required_dimensions: []
18
+ direction: null
19
+ unit: null
20
+ significant_digits: 2
21
+ min_decimal_exponent: null
22
+ max_decimal_exponent: null
@@ -0,0 +1,148 @@
1
+ name: ${prefix}namespace
2
+ node_type: dimension
3
+ display_name: Namespace
4
+ description: |-
5
+ One row per distinct DJ namespace. Repo-related attributes are derived by
6
+ walking the nodenamespace tree:
7
+
8
+ - ``repo_container`` is the longest-prefix namespace that holds a
9
+ ``github_repo_path`` (the "repo container", e.g. ``ads``).
10
+ - ``branch_namespace`` is the longest-prefix namespace under that
11
+ container that has its own ``git_branch`` set.
12
+ - ``trunk_namespace`` is conventionally ``repo_container.default_branch``
13
+ (e.g. ``ads.main``).
14
+ query: |-
15
+ WITH ns AS (
16
+ -- Every distinct namespace that DJ knows about: every namespace
17
+ -- containing a node, plus every nodenamespace row (so container /
18
+ -- empty namespaces like ``customer_service`` are still represented).
19
+ SELECT DISTINCT namespace
20
+ FROM source.dj_metadata.public.node
21
+ WHERE namespace IS NOT NULL
22
+ UNION
23
+ SELECT namespace
24
+ FROM source.dj_metadata.public.nodenamespace
25
+ ),
26
+ deployed_ns AS (
27
+ SELECT DISTINCT namespace
28
+ FROM source.dj_metadata.public.deployments
29
+ ),
30
+ repo_containers AS (
31
+ SELECT
32
+ NN.namespace AS container,
33
+ NN.github_repo_path,
34
+ NN.default_branch,
35
+ NN.git_only,
36
+ NN.namespace || '.' || NN.default_branch AS trunk_namespace
37
+ FROM source.dj_metadata.public.nodenamespace NN
38
+ WHERE NN.parent_namespace IS NULL
39
+ AND NN.github_repo_path IS NOT NULL
40
+ ),
41
+ branch_rows AS (
42
+ SELECT
43
+ NN.namespace AS branch_namespace,
44
+ NN.parent_namespace,
45
+ NN.git_branch
46
+ FROM source.dj_metadata.public.nodenamespace NN
47
+ WHERE NN.parent_namespace IS NOT NULL
48
+ AND NN.git_branch IS NOT NULL
49
+ ),
50
+ ns_repo_match AS (
51
+ SELECT
52
+ ns.namespace,
53
+ rc.container,
54
+ rc.github_repo_path,
55
+ rc.default_branch,
56
+ rc.git_only,
57
+ rc.trunk_namespace,
58
+ ROW_NUMBER() OVER (
59
+ PARTITION BY ns.namespace ORDER BY LENGTH(rc.container) DESC
60
+ ) AS rn
61
+ FROM ns
62
+ JOIN repo_containers rc
63
+ ON ns.namespace = rc.container OR ns.namespace LIKE rc.container || '.%'
64
+ ),
65
+ ns_repo AS (
66
+ SELECT namespace, container, github_repo_path, default_branch, git_only,
67
+ trunk_namespace
68
+ FROM ns_repo_match
69
+ WHERE rn = 1
70
+ ),
71
+ ns_branch_match AS (
72
+ SELECT
73
+ ns.namespace,
74
+ br.branch_namespace,
75
+ br.git_branch,
76
+ ROW_NUMBER() OVER (
77
+ PARTITION BY ns.namespace ORDER BY LENGTH(br.branch_namespace) DESC
78
+ ) AS rn
79
+ FROM ns
80
+ JOIN branch_rows br
81
+ ON ns.namespace = br.branch_namespace
82
+ OR ns.namespace LIKE br.branch_namespace || '.%'
83
+ ),
84
+ ns_branch AS (
85
+ SELECT namespace, branch_namespace, git_branch
86
+ FROM ns_branch_match
87
+ WHERE rn = 1
88
+ )
89
+ SELECT
90
+ ns.namespace AS name,
91
+ CASE WHEN deployed_ns.namespace IS NOT NULL
92
+ THEN true ELSE false END AS has_deployments,
93
+ CAST(SPLIT_PART(ns.namespace, '.', 1) AS STRING) AS top_level,
94
+ CAST(LENGTH(ns.namespace) - LENGTH(REPLACE(ns.namespace, '.', '')) + 1 AS integer) AS depth,
95
+ ns_repo.github_repo_path AS github_repo_path,
96
+ ns_repo.container AS repo_container,
97
+ ns_repo.trunk_namespace AS trunk_namespace,
98
+ COALESCE(ns_branch.git_branch, ns_repo.default_branch) AS git_branch,
99
+ CASE WHEN ns_repo.github_repo_path IS NOT NULL
100
+ THEN true ELSE false END AS is_repo_backed,
101
+ CASE WHEN ns.namespace = ns_repo.container
102
+ THEN true ELSE false END AS is_repo_container,
103
+ CASE WHEN ns.namespace = ns_repo.trunk_namespace
104
+ THEN true ELSE false END AS is_trunk_namespace,
105
+ CASE
106
+ WHEN ns_branch.branch_namespace IS NOT NULL
107
+ AND ns_branch.branch_namespace != ns_repo.trunk_namespace
108
+ THEN true ELSE false
109
+ END AS is_branch_namespace
110
+ FROM ns
111
+ LEFT JOIN deployed_ns ON ns.namespace = deployed_ns.namespace
112
+ LEFT JOIN ns_repo ON ns.namespace = ns_repo.namespace
113
+ LEFT JOIN ns_branch ON ns.namespace = ns_branch.namespace
114
+ columns:
115
+ - name: name
116
+ display_name: Namespace
117
+ - name: top_level
118
+ display_name: Top-level Namespace
119
+ - name: depth
120
+ display_name: Namespace Depth
121
+ - name: has_deployments
122
+ display_name: Has Deployments
123
+ - name: github_repo_path
124
+ display_name: Repository
125
+ attributes:
126
+ - hidden
127
+ - name: repo_container
128
+ display_name: Repo Container
129
+ - name: trunk_namespace
130
+ display_name: Trunk Namespace
131
+ - name: git_branch
132
+ display_name: Git Branch
133
+ - name: is_repo_backed
134
+ display_name: Is Repo-Backed
135
+ - name: is_repo_container
136
+ display_name: Is Repo Container
137
+ - name: is_trunk_namespace
138
+ display_name: Is Trunk Namespace
139
+ - name: is_branch_namespace
140
+ display_name: Is Branch Namespace
141
+ primary_key:
142
+ - name
143
+ dimension_links:
144
+ - type: join
145
+ dimension_node: ${prefix}repo
146
+ join_type: left
147
+ join_on: ${prefix}namespace.github_repo_path = ${prefix}repo.repository
148
+ tags: []