datajunction 0.0.97__tar.gz → 0.0.99__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 (169) hide show
  1. {datajunction-0.0.97 → datajunction-0.0.99}/PKG-INFO +1 -1
  2. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/__about__.py +1 -1
  3. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/cli.py +25 -3
  4. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/deployment.py +3 -0
  5. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples.py +45 -0
  6. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_cli.py +41 -0
  7. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_deploy.py +44 -0
  8. {datajunction-0.0.97 → datajunction-0.0.99}/.coveragerc +0 -0
  9. {datajunction-0.0.97 → datajunction-0.0.99}/.gitignore +0 -0
  10. {datajunction-0.0.97 → datajunction-0.0.99}/.isort.cfg +0 -0
  11. {datajunction-0.0.97 → datajunction-0.0.99}/.pre-commit-config.yaml +0 -0
  12. {datajunction-0.0.97 → datajunction-0.0.99}/LICENSE.txt +0 -0
  13. {datajunction-0.0.97 → datajunction-0.0.99}/Makefile +0 -0
  14. {datajunction-0.0.97 → datajunction-0.0.99}/README.md +0 -0
  15. {datajunction-0.0.97 → datajunction-0.0.99}/claude_desktop_config.example.json +0 -0
  16. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/__init__.py +0 -0
  17. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/_base.py +0 -0
  18. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/_internal.py +0 -0
  19. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/admin.py +0 -0
  20. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/builder.py +0 -0
  21. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/client.py +0 -0
  22. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/compile.py +0 -0
  23. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/exceptions.py +0 -0
  24. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/mcp/__init__.py +0 -0
  25. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/mcp/cli.py +0 -0
  26. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/mcp/config.py +0 -0
  27. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/mcp/formatters.py +0 -0
  28. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/mcp/server.py +0 -0
  29. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/mcp/tools.py +0 -0
  30. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/models.py +0 -0
  31. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/nodes.py +0 -0
  32. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/init_system_nodes.py +0 -0
  33. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/date.dimension.yaml +0 -0
  34. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/dimension_link.dimension.yaml +0 -0
  35. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/dj.yaml +0 -0
  36. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/is_active.dimension.yaml +0 -0
  37. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/materialization.dimension.yaml +0 -0
  38. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/node_type.dimension.yaml +0 -0
  39. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/node_without_description.metric.yaml +0 -0
  40. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/nodes.dimension.yaml +0 -0
  41. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/number_of_materializations.metric.yaml +0 -0
  42. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/number_of_nodes.metric.yaml +0 -0
  43. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/seed/nodes/user.dimension.yaml +0 -0
  44. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/skills/datajunction.md +0 -0
  45. {datajunction-0.0.97 → datajunction-0.0.99}/datajunction/tags.py +0 -0
  46. {datajunction-0.0.97 → datajunction-0.0.99}/pyproject.toml +0 -0
  47. {datajunction-0.0.97 → datajunction-0.0.99}/setup.cfg +0 -0
  48. {datajunction-0.0.97 → datajunction-0.0.99}/tests/__init__.py +0 -0
  49. {datajunction-0.0.97 → datajunction-0.0.99}/tests/conftest.py +0 -0
  50. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/deploy0/dj.yaml +0 -0
  51. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/deploy0/roads/companies.yaml +0 -0
  52. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/deploy0/roads/companies_dim.yaml +0 -0
  53. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/deploy0/roads/contractor.yaml +0 -0
  54. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/deploy0/roads/contractors.yaml +0 -0
  55. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/deploy0/roads/us_state.yaml +0 -0
  56. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/deploy0/roads/us_states.yaml +0 -0
  57. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/dj.yaml +0 -0
  58. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/avg_length_of_employment.metric.yaml +0 -0
  59. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/avg_repair_price.metric.yaml +0 -0
  60. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/avg_time_to_dispatch.metric.yaml +0 -0
  61. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/contractor.dimension.yaml +0 -0
  62. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/contractors.source.yaml +0 -0
  63. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/date.source.yaml +0 -0
  64. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/date_dim.dimension.yaml +0 -0
  65. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/dispatcher.dimension.yaml +0 -0
  66. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/dispatchers.source.yaml +0 -0
  67. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/hard_hat.dimension.yaml +0 -0
  68. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/hard_hat_state.source.yaml +0 -0
  69. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/hard_hats.source.yaml +0 -0
  70. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/local_hard_hats.dimension.yaml +0 -0
  71. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/municipality.source.yaml +0 -0
  72. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/municipality_dim.dimension.yaml +0 -0
  73. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/municipality_municipality_type.source.yaml +0 -0
  74. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/municipality_type.source.yaml +0 -0
  75. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/national_level_agg.transform.yaml +0 -0
  76. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/num_repair_orders.metric.yaml +0 -0
  77. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/regional_level_agg.transform.yaml +0 -0
  78. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/regional_repair_efficiency.metric.yaml +0 -0
  79. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/repair_order.dimension.yaml +0 -0
  80. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/repair_order_details.source.yaml +0 -0
  81. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/repair_order_transform.transform.yaml +0 -0
  82. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/repair_orders.source.yaml +0 -0
  83. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/repair_orders_cube.cube.yaml +0 -0
  84. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/repair_type.source.yaml +0 -0
  85. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/total_repair_cost.metric.yaml +0 -0
  86. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/total_repair_order_discounts.metric.yaml +0 -0
  87. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/us_region.source.yaml +0 -0
  88. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/us_state.dimension.yaml +0 -0
  89. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project1/roads/us_states.source.yaml +0 -0
  90. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project10/dj.yaml +0 -0
  91. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/avg_length_of_employment.metric.yaml +0 -0
  92. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/avg_repair_price.metric.yaml +0 -0
  93. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/avg_time_to_dispatch.metric.yaml +0 -0
  94. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/contractor.dimension.yaml +0 -0
  95. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/contractors.source.yaml +0 -0
  96. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/date.source.yaml +0 -0
  97. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/date_dim.dimension.yaml +0 -0
  98. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/dispatcher.dimension.yaml +0 -0
  99. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/dispatchers.source.yaml +0 -0
  100. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/dj.yaml +0 -0
  101. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/hard_hat.dimension.yaml +0 -0
  102. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/hard_hat_state.source.yaml +0 -0
  103. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/hard_hats.source.yaml +0 -0
  104. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/local_hard_hats.dimension.yaml +0 -0
  105. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/municipality.source.yaml +0 -0
  106. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/municipality_dim.dimension.yaml +0 -0
  107. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/municipality_municipality_type.source.yaml +0 -0
  108. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/municipality_type.source.yaml +0 -0
  109. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/national_level_agg.transform.yaml +0 -0
  110. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/num_repair_orders.metric.yaml +0 -0
  111. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/regional_level_agg.transform.yaml +0 -0
  112. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/regional_repair_efficiency.metric.yaml +0 -0
  113. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/repair_order.dimension.yaml +0 -0
  114. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/repair_order_details.source.yaml +0 -0
  115. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/repair_order_transform.transform.yaml +0 -0
  116. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/repair_orders.source.yaml +0 -0
  117. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/repair_orders_cube.cube.yaml +0 -0
  118. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/repair_type.source.yaml +0 -0
  119. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/total_repair_cost.metric.yaml +0 -0
  120. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/total_repair_order_discounts.metric.yaml +0 -0
  121. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/us_region.source.yaml +0 -0
  122. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/us_state.dimension.yaml +0 -0
  123. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project11/us_states.source.yaml +0 -0
  124. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project12/dj.yaml +0 -0
  125. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project12/roads/companies.source.yaml +0 -0
  126. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project12/roads/companies_dim.dimension.yaml +0 -0
  127. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project12/roads/contractor.dimension.yaml +0 -0
  128. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project12/roads/contractors.source.yaml +0 -0
  129. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project12/roads/us_state.dimension.yaml +0 -0
  130. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project12/roads/us_states.source.yaml +0 -0
  131. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project2/dj.yaml +0 -0
  132. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project2/some_node.source.yaml +0 -0
  133. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project3/dj.yaml +0 -0
  134. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project3/some_node.yaml +0 -0
  135. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project4/dj.yaml +0 -0
  136. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project4/very/very/deeply/nested/namespace/some_node.source.yaml +0 -0
  137. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project5/dj.yaml +0 -0
  138. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project5/some_node.a.b.c.source.yaml +0 -0
  139. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project6/dj.yaml +0 -0
  140. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project6/roads/contractor.dimension.yaml +0 -0
  141. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project6/roads/contractors.source.yaml +0 -0
  142. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project7/dj.yaml +0 -0
  143. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project7/roads/contractor.dimension.yaml +0 -0
  144. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project7/roads/contractors.source.yaml +0 -0
  145. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project8/dj.yaml +0 -0
  146. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project9/dj.yaml +0 -0
  147. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project9/roads/companies.source.yaml +0 -0
  148. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project9/roads/companies_dim.dimension.yaml +0 -0
  149. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project9/roads/contractor.dimension.yaml +0 -0
  150. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project9/roads/contractors.source.yaml +0 -0
  151. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project9/roads/us_state.dimension.yaml +0 -0
  152. {datajunction-0.0.97 → datajunction-0.0.99}/tests/examples/project9/roads/us_states.source.yaml +0 -0
  153. {datajunction-0.0.97 → datajunction-0.0.99}/tests/mcp/README.md +0 -0
  154. {datajunction-0.0.97 → datajunction-0.0.99}/tests/mcp/__init__.py +0 -0
  155. {datajunction-0.0.97 → datajunction-0.0.99}/tests/mcp/test_cli.py +0 -0
  156. {datajunction-0.0.97 → datajunction-0.0.99}/tests/mcp/test_formatters.py +0 -0
  157. {datajunction-0.0.97 → datajunction-0.0.99}/tests/mcp/test_server_tools.py +0 -0
  158. {datajunction-0.0.97 → datajunction-0.0.99}/tests/mcp/test_tools.py +0 -0
  159. {datajunction-0.0.97 → datajunction-0.0.99}/tests/mcp/test_visualize_metrics.py +0 -0
  160. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test__internal.py +0 -0
  161. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_admin.py +0 -0
  162. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_base.py +0 -0
  163. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_builder.py +0 -0
  164. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_client.py +0 -0
  165. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_compile.py +0 -0
  166. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_generated_client.py +0 -0
  167. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_integration.py +0 -0
  168. {datajunction-0.0.97 → datajunction-0.0.99}/tests/test_models.py +0 -0
  169. {datajunction-0.0.97 → datajunction-0.0.99}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datajunction
3
- Version: 0.0.97
3
+ Version: 0.0.99
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.97"
5
+ __version__ = "0.0.99"
@@ -252,11 +252,22 @@ class DJCLI:
252
252
  self.builder_client = builder_client
253
253
  self.deployment_service = DeploymentService(client=self.builder_client)
254
254
 
255
- def push(self, directory: str, namespace: str | None = None, verbose: bool = False):
255
+ def push(
256
+ self,
257
+ directory: str,
258
+ namespace: str | None = None,
259
+ verbose: bool = False,
260
+ force: bool = False,
261
+ ):
256
262
  """
257
263
  Alias for deploy without dryrun.
258
264
  """
259
- self.deployment_service.push(directory, namespace=namespace, verbose=verbose)
265
+ self.deployment_service.push(
266
+ directory,
267
+ namespace=namespace,
268
+ verbose=verbose,
269
+ force=force,
270
+ )
260
271
 
261
272
  def dryrun(
262
273
  self,
@@ -875,6 +886,11 @@ class DJCLI:
875
886
  action="store_true",
876
887
  help="Show all results including noops",
877
888
  )
889
+ deploy_parser.add_argument(
890
+ "--force",
891
+ action="store_true",
892
+ help="Force update all nodes even if they are unchanged",
893
+ )
878
894
 
879
895
  # `dj push <directory>` - primary deployment command
880
896
  push_parser = subparsers.add_parser(
@@ -901,6 +917,11 @@ class DJCLI:
901
917
  action="store_true",
902
918
  help="Show all results including noops",
903
919
  )
920
+ push_parser.add_argument(
921
+ "--force",
922
+ action="store_true",
923
+ help="Force update all nodes even if they are unchanged",
924
+ )
904
925
  push_parser.add_argument(
905
926
  "--format",
906
927
  type=str,
@@ -1301,7 +1322,7 @@ class DJCLI:
1301
1322
  self.dryrun(args.directory, format=args.format)
1302
1323
  return
1303
1324
  try:
1304
- self.push(args.directory, verbose=args.verbose)
1325
+ self.push(args.directory, verbose=args.verbose, force=args.force)
1305
1326
  except DJDeploymentFailure:
1306
1327
  raise SystemExit(1)
1307
1328
  elif args.command == "push":
@@ -1329,6 +1350,7 @@ class DJCLI:
1329
1350
  args.directory,
1330
1351
  namespace=args.namespace,
1331
1352
  verbose=args.verbose,
1353
+ force=args.force,
1332
1354
  )
1333
1355
  except DJDeploymentFailure:
1334
1356
  raise SystemExit(1)
@@ -249,6 +249,7 @@ class DeploymentService:
249
249
  namespace: str | None = None,
250
250
  console: Console | None = None,
251
251
  verbose: bool = False,
252
+ force: bool = False,
252
253
  ):
253
254
  """
254
255
  Push a local project to a namespace.
@@ -293,6 +294,8 @@ class DeploymentService:
293
294
  f"[yellow]Warning: could not set git config on namespace "
294
295
  f"'{deployment_spec['namespace']}': {e}[/yellow]",
295
296
  )
297
+ if force:
298
+ deployment_spec["force"] = True
296
299
  deployment_data = self.client.deploy(deployment_spec)
297
300
  deployment_uuid = deployment_data["uuid"]
298
301
 
@@ -1469,4 +1469,49 @@ QUERY_DATA_MAPPINGS: Dict[str, Union[DJException, QueryWithResults]] = {
1469
1469
  results=[],
1470
1470
  errors=[],
1471
1471
  ),
1472
+ # v3 API query for avg_repair_price with city dimension (with hard_hat_id in repair_order CTE)
1473
+ # This SQL is generated after the fix-filter-role PR which adds join key columns to CTEs
1474
+ "WITHdefault_hard_hatAS(SELECThard_hat_id,\tcityFROMdefault.roads.hard_hats),"
1475
+ "default_repair_orderAS(SELECTrepair_order_id,\thard_hat_idFROMdefault.repair_orders),"
1476
+ "repair_order_details_0AS(SELECTt3.city,\tCOUNT(t1.price)price_count_252381cf,"
1477
+ "\tSUM(t1.price)price_sum_252381cfFROMdefault.roads.repair_order_detailst1"
1478
+ "LEFTOUTERJOINdefault_repair_ordert2ONt1.repair_order_id=t2.repair_order_id"
1479
+ "LEFTOUTERJOINdefault_hard_hatt3ONt2.hard_hat_id=t3.hard_hat_idGROUPBYt3.city)"
1480
+ "SELECTrepair_order_details_0.cityAScity,\tSUM(repair_order_details_0."
1481
+ "price_sum_252381cf)/SUM(repair_order_details_0.price_count_252381cf)AS"
1482
+ "avg_repair_priceFROMrepair_order_details_0GROUPBYrepair_order_details_0.city": QueryWithResults(
1483
+ id="v3-avg-repair-price-city-with-join-key",
1484
+ submitted_query="...",
1485
+ state=QueryState.FINISHED,
1486
+ results=[
1487
+ {
1488
+ "columns": [
1489
+ {"name": "city", "type": "str"},
1490
+ {"name": "avg_repair_price", "type": "float"},
1491
+ ],
1492
+ "rows": [
1493
+ ("Foo", 1.0),
1494
+ ("Bar", 2.0),
1495
+ ],
1496
+ "sql": "",
1497
+ },
1498
+ ],
1499
+ errors=[],
1500
+ ),
1501
+ # v3 API query for avg_repair_price with state dimension (with hard_hat_id in repair_order CTE)
1502
+ "WITHdefault_hard_hatAS(SELECThard_hat_id,\tstateFROMdefault.roads.hard_hats),"
1503
+ "default_repair_orderAS(SELECTrepair_order_id,\thard_hat_idFROMdefault.repair_orders),"
1504
+ "repair_order_details_0AS(SELECTt3.state,\tCOUNT(t1.price)price_count_252381cf,"
1505
+ "\tSUM(t1.price)price_sum_252381cfFROMdefault.roads.repair_order_detailst1"
1506
+ "LEFTOUTERJOINdefault_repair_ordert2ONt1.repair_order_id=t2.repair_order_id"
1507
+ "LEFTOUTERJOINdefault_hard_hatt3ONt2.hard_hat_id=t3.hard_hat_idGROUPBYt3.state)"
1508
+ "SELECTrepair_order_details_0.stateASstate,\tSUM(repair_order_details_0."
1509
+ "price_sum_252381cf)/SUM(repair_order_details_0.price_count_252381cf)AS"
1510
+ "avg_repair_priceFROMrepair_order_details_0GROUPBYrepair_order_details_0.state": QueryWithResults(
1511
+ id="v3-avg-repair-price-state-no-data-with-join-key",
1512
+ submitted_query="...",
1513
+ state=QueryState.FINISHED,
1514
+ results=[],
1515
+ errors=[],
1516
+ ),
1472
1517
  }
@@ -1679,6 +1679,47 @@ class TestImpactAnalysis:
1679
1679
  # deploy0 has 6 nodes, they should be deployed
1680
1680
  assert len(results) >= 6
1681
1681
 
1682
+ def test_push_force_flag_passed_to_service(self, tmp_path):
1683
+ """--force on `dj push` must propagate force=True to DeploymentService.push."""
1684
+ from datajunction.cli import DJCLI
1685
+
1686
+ cli = DJCLI(builder_client=mock.MagicMock())
1687
+ with patch.object(cli.deployment_service, "push") as mock_push:
1688
+ mock_push.return_value = None
1689
+ with patch.object(sys, "argv", ["dj", "push", str(tmp_path), "--force"]):
1690
+ cli.run()
1691
+
1692
+ mock_push.assert_called_once()
1693
+ _, kwargs = mock_push.call_args
1694
+ assert kwargs.get("force") is True
1695
+
1696
+ def test_deploy_force_flag_passed_to_service(self, tmp_path):
1697
+ """--force on `dj deploy` must propagate force=True to DeploymentService.push."""
1698
+ from datajunction.cli import DJCLI
1699
+
1700
+ cli = DJCLI(builder_client=mock.MagicMock())
1701
+ with patch.object(cli.deployment_service, "push") as mock_push:
1702
+ mock_push.return_value = None
1703
+ with patch.object(sys, "argv", ["dj", "deploy", str(tmp_path), "--force"]):
1704
+ cli.run()
1705
+
1706
+ mock_push.assert_called_once()
1707
+ _, kwargs = mock_push.call_args
1708
+ assert kwargs.get("force") is True
1709
+
1710
+ def test_push_without_force_flag_defaults_false(self, tmp_path):
1711
+ """Omitting --force on `dj push` must pass force=False."""
1712
+ from datajunction.cli import DJCLI
1713
+
1714
+ cli = DJCLI(builder_client=mock.MagicMock())
1715
+ with patch.object(cli.deployment_service, "push") as mock_push:
1716
+ mock_push.return_value = None
1717
+ with patch.object(sys, "argv", ["dj", "push", str(tmp_path)]):
1718
+ cli.run()
1719
+
1720
+ _, kwargs = mock_push.call_args
1721
+ assert kwargs.get("force") is False
1722
+
1682
1723
 
1683
1724
  class TestDJCLIClientCreation:
1684
1725
  """Tests for DJCLI client creation from environment variables."""
@@ -274,6 +274,50 @@ def test_push_waits_until_success(monkeypatch, tmp_path):
274
274
  client.check_deployment.assert_called()
275
275
 
276
276
 
277
+ def test_push_force_sets_flag_in_spec(monkeypatch, tmp_path):
278
+ """push(force=True) must include {"force": True} in the spec sent to client.deploy."""
279
+ (tmp_path / "dj.yaml").write_text(yaml.safe_dump({"namespace": "foo"}))
280
+ (tmp_path / "foo.yaml").write_text(yaml.safe_dump({"name": "foo.bar"}))
281
+
282
+ client = MagicMock()
283
+ client.deploy.return_value = {
284
+ "uuid": "abc",
285
+ "status": "success",
286
+ "results": [],
287
+ "namespace": "foo",
288
+ }
289
+
290
+ svc = DeploymentService(client, console=Console(file=io.StringIO()))
291
+ monkeypatch.setattr(time, "sleep", lambda _: None)
292
+
293
+ svc.push(tmp_path, force=True)
294
+
295
+ spec_sent = client.deploy.call_args[0][0]
296
+ assert spec_sent.get("force") is True
297
+
298
+
299
+ def test_push_without_force_does_not_set_flag(monkeypatch, tmp_path):
300
+ """push() without force must not include force in the spec (server default handles it)."""
301
+ (tmp_path / "dj.yaml").write_text(yaml.safe_dump({"namespace": "foo"}))
302
+ (tmp_path / "foo.yaml").write_text(yaml.safe_dump({"name": "foo.bar"}))
303
+
304
+ client = MagicMock()
305
+ client.deploy.return_value = {
306
+ "uuid": "abc",
307
+ "status": "success",
308
+ "results": [],
309
+ "namespace": "foo",
310
+ }
311
+
312
+ svc = DeploymentService(client, console=Console(file=io.StringIO()))
313
+ monkeypatch.setattr(time, "sleep", lambda _: None)
314
+
315
+ svc.push(tmp_path)
316
+
317
+ spec_sent = client.deploy.call_args[0][0]
318
+ assert "force" not in spec_sent
319
+
320
+
277
321
  def test_push_times_out(monkeypatch, tmp_path):
278
322
  # minimal project structure so _reconstruct_deployment_spec works
279
323
  (tmp_path / "dj.yaml").write_text(yaml.safe_dump({"namespace": "foo"}))
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes