dvt-core 0.52.2__cp310-cp310-macosx_10_9_x86_64.whl

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.

Potentially problematic release.


This version of dvt-core might be problematic. Click here for more details.

Files changed (275) hide show
  1. dbt/__init__.py +7 -0
  2. dbt/_pydantic_shim.py +26 -0
  3. dbt/artifacts/__init__.py +0 -0
  4. dbt/artifacts/exceptions/__init__.py +1 -0
  5. dbt/artifacts/exceptions/schemas.py +31 -0
  6. dbt/artifacts/resources/__init__.py +116 -0
  7. dbt/artifacts/resources/base.py +67 -0
  8. dbt/artifacts/resources/types.py +93 -0
  9. dbt/artifacts/resources/v1/analysis.py +10 -0
  10. dbt/artifacts/resources/v1/catalog.py +23 -0
  11. dbt/artifacts/resources/v1/components.py +274 -0
  12. dbt/artifacts/resources/v1/config.py +277 -0
  13. dbt/artifacts/resources/v1/documentation.py +11 -0
  14. dbt/artifacts/resources/v1/exposure.py +51 -0
  15. dbt/artifacts/resources/v1/function.py +52 -0
  16. dbt/artifacts/resources/v1/generic_test.py +31 -0
  17. dbt/artifacts/resources/v1/group.py +21 -0
  18. dbt/artifacts/resources/v1/hook.py +11 -0
  19. dbt/artifacts/resources/v1/macro.py +29 -0
  20. dbt/artifacts/resources/v1/metric.py +172 -0
  21. dbt/artifacts/resources/v1/model.py +145 -0
  22. dbt/artifacts/resources/v1/owner.py +10 -0
  23. dbt/artifacts/resources/v1/saved_query.py +111 -0
  24. dbt/artifacts/resources/v1/seed.py +41 -0
  25. dbt/artifacts/resources/v1/semantic_layer_components.py +72 -0
  26. dbt/artifacts/resources/v1/semantic_model.py +314 -0
  27. dbt/artifacts/resources/v1/singular_test.py +14 -0
  28. dbt/artifacts/resources/v1/snapshot.py +91 -0
  29. dbt/artifacts/resources/v1/source_definition.py +84 -0
  30. dbt/artifacts/resources/v1/sql_operation.py +10 -0
  31. dbt/artifacts/resources/v1/unit_test_definition.py +77 -0
  32. dbt/artifacts/schemas/__init__.py +0 -0
  33. dbt/artifacts/schemas/base.py +191 -0
  34. dbt/artifacts/schemas/batch_results.py +24 -0
  35. dbt/artifacts/schemas/catalog/__init__.py +11 -0
  36. dbt/artifacts/schemas/catalog/v1/__init__.py +0 -0
  37. dbt/artifacts/schemas/catalog/v1/catalog.py +59 -0
  38. dbt/artifacts/schemas/freshness/__init__.py +1 -0
  39. dbt/artifacts/schemas/freshness/v3/__init__.py +0 -0
  40. dbt/artifacts/schemas/freshness/v3/freshness.py +158 -0
  41. dbt/artifacts/schemas/manifest/__init__.py +2 -0
  42. dbt/artifacts/schemas/manifest/v12/__init__.py +0 -0
  43. dbt/artifacts/schemas/manifest/v12/manifest.py +211 -0
  44. dbt/artifacts/schemas/results.py +147 -0
  45. dbt/artifacts/schemas/run/__init__.py +2 -0
  46. dbt/artifacts/schemas/run/v5/__init__.py +0 -0
  47. dbt/artifacts/schemas/run/v5/run.py +184 -0
  48. dbt/artifacts/schemas/upgrades/__init__.py +4 -0
  49. dbt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
  50. dbt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
  51. dbt/artifacts/utils/validation.py +153 -0
  52. dbt/cli/__init__.py +1 -0
  53. dbt/cli/context.py +17 -0
  54. dbt/cli/exceptions.py +57 -0
  55. dbt/cli/flags.py +560 -0
  56. dbt/cli/main.py +2039 -0
  57. dbt/cli/option_types.py +121 -0
  58. dbt/cli/options.py +80 -0
  59. dbt/cli/params.py +804 -0
  60. dbt/cli/requires.py +490 -0
  61. dbt/cli/resolvers.py +50 -0
  62. dbt/cli/types.py +40 -0
  63. dbt/clients/__init__.py +0 -0
  64. dbt/clients/checked_load.py +83 -0
  65. dbt/clients/git.py +164 -0
  66. dbt/clients/jinja.py +206 -0
  67. dbt/clients/jinja_static.py +245 -0
  68. dbt/clients/registry.py +192 -0
  69. dbt/clients/yaml_helper.py +68 -0
  70. dbt/compilation.py +876 -0
  71. dbt/compute/__init__.py +14 -0
  72. dbt/compute/engines/__init__.py +12 -0
  73. dbt/compute/engines/spark_engine.py +624 -0
  74. dbt/compute/federated_executor.py +837 -0
  75. dbt/compute/filter_pushdown.cpython-310-darwin.so +0 -0
  76. dbt/compute/filter_pushdown.py +273 -0
  77. dbt/compute/jar_provisioning.cpython-310-darwin.so +0 -0
  78. dbt/compute/jar_provisioning.py +255 -0
  79. dbt/compute/java_compat.cpython-310-darwin.so +0 -0
  80. dbt/compute/java_compat.py +689 -0
  81. dbt/compute/jdbc_utils.cpython-310-darwin.so +0 -0
  82. dbt/compute/jdbc_utils.py +678 -0
  83. dbt/compute/smart_selector.cpython-310-darwin.so +0 -0
  84. dbt/compute/smart_selector.py +311 -0
  85. dbt/compute/strategies/__init__.py +54 -0
  86. dbt/compute/strategies/base.py +165 -0
  87. dbt/compute/strategies/dataproc.py +207 -0
  88. dbt/compute/strategies/emr.py +203 -0
  89. dbt/compute/strategies/local.py +364 -0
  90. dbt/compute/strategies/standalone.py +262 -0
  91. dbt/config/__init__.py +4 -0
  92. dbt/config/catalogs.py +94 -0
  93. dbt/config/compute.cpython-310-darwin.so +0 -0
  94. dbt/config/compute.py +547 -0
  95. dbt/config/dvt_profile.cpython-310-darwin.so +0 -0
  96. dbt/config/dvt_profile.py +342 -0
  97. dbt/config/profile.py +422 -0
  98. dbt/config/project.py +873 -0
  99. dbt/config/project_utils.py +28 -0
  100. dbt/config/renderer.py +231 -0
  101. dbt/config/runtime.py +553 -0
  102. dbt/config/selectors.py +208 -0
  103. dbt/config/utils.py +77 -0
  104. dbt/constants.py +28 -0
  105. dbt/context/__init__.py +0 -0
  106. dbt/context/base.py +745 -0
  107. dbt/context/configured.py +135 -0
  108. dbt/context/context_config.py +382 -0
  109. dbt/context/docs.py +82 -0
  110. dbt/context/exceptions_jinja.py +178 -0
  111. dbt/context/macro_resolver.py +195 -0
  112. dbt/context/macros.py +171 -0
  113. dbt/context/manifest.py +72 -0
  114. dbt/context/providers.py +2249 -0
  115. dbt/context/query_header.py +13 -0
  116. dbt/context/secret.py +58 -0
  117. dbt/context/target.py +74 -0
  118. dbt/contracts/__init__.py +0 -0
  119. dbt/contracts/files.py +413 -0
  120. dbt/contracts/graph/__init__.py +0 -0
  121. dbt/contracts/graph/manifest.py +1904 -0
  122. dbt/contracts/graph/metrics.py +97 -0
  123. dbt/contracts/graph/model_config.py +70 -0
  124. dbt/contracts/graph/node_args.py +42 -0
  125. dbt/contracts/graph/nodes.py +1806 -0
  126. dbt/contracts/graph/semantic_manifest.py +232 -0
  127. dbt/contracts/graph/unparsed.py +811 -0
  128. dbt/contracts/project.py +417 -0
  129. dbt/contracts/results.py +53 -0
  130. dbt/contracts/selection.py +23 -0
  131. dbt/contracts/sql.py +85 -0
  132. dbt/contracts/state.py +68 -0
  133. dbt/contracts/util.py +46 -0
  134. dbt/deprecations.py +346 -0
  135. dbt/deps/__init__.py +0 -0
  136. dbt/deps/base.py +152 -0
  137. dbt/deps/git.py +195 -0
  138. dbt/deps/local.py +79 -0
  139. dbt/deps/registry.py +130 -0
  140. dbt/deps/resolver.py +149 -0
  141. dbt/deps/tarball.py +120 -0
  142. dbt/docs/source/_ext/dbt_click.py +119 -0
  143. dbt/docs/source/conf.py +32 -0
  144. dbt/env_vars.py +64 -0
  145. dbt/event_time/event_time.py +40 -0
  146. dbt/event_time/sample_window.py +60 -0
  147. dbt/events/__init__.py +15 -0
  148. dbt/events/base_types.py +36 -0
  149. dbt/events/core_types_pb2.py +2 -0
  150. dbt/events/logging.py +108 -0
  151. dbt/events/types.py +2516 -0
  152. dbt/exceptions.py +1486 -0
  153. dbt/flags.py +89 -0
  154. dbt/graph/__init__.py +11 -0
  155. dbt/graph/cli.py +247 -0
  156. dbt/graph/graph.py +172 -0
  157. dbt/graph/queue.py +214 -0
  158. dbt/graph/selector.py +374 -0
  159. dbt/graph/selector_methods.py +975 -0
  160. dbt/graph/selector_spec.py +222 -0
  161. dbt/graph/thread_pool.py +18 -0
  162. dbt/hooks.py +21 -0
  163. dbt/include/README.md +49 -0
  164. dbt/include/__init__.py +3 -0
  165. dbt/include/starter_project/.gitignore +4 -0
  166. dbt/include/starter_project/README.md +15 -0
  167. dbt/include/starter_project/__init__.py +3 -0
  168. dbt/include/starter_project/analyses/.gitkeep +0 -0
  169. dbt/include/starter_project/dbt_project.yml +36 -0
  170. dbt/include/starter_project/macros/.gitkeep +0 -0
  171. dbt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
  172. dbt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
  173. dbt/include/starter_project/models/example/schema.yml +21 -0
  174. dbt/include/starter_project/seeds/.gitkeep +0 -0
  175. dbt/include/starter_project/snapshots/.gitkeep +0 -0
  176. dbt/include/starter_project/tests/.gitkeep +0 -0
  177. dbt/internal_deprecations.py +26 -0
  178. dbt/jsonschemas/__init__.py +3 -0
  179. dbt/jsonschemas/jsonschemas.py +309 -0
  180. dbt/jsonschemas/project/0.0.110.json +4717 -0
  181. dbt/jsonschemas/project/0.0.85.json +2015 -0
  182. dbt/jsonschemas/resources/0.0.110.json +2636 -0
  183. dbt/jsonschemas/resources/0.0.85.json +2536 -0
  184. dbt/jsonschemas/resources/latest.json +6773 -0
  185. dbt/links.py +4 -0
  186. dbt/materializations/__init__.py +0 -0
  187. dbt/materializations/incremental/__init__.py +0 -0
  188. dbt/materializations/incremental/microbatch.py +236 -0
  189. dbt/mp_context.py +8 -0
  190. dbt/node_types.py +37 -0
  191. dbt/parser/__init__.py +23 -0
  192. dbt/parser/analysis.py +21 -0
  193. dbt/parser/base.py +548 -0
  194. dbt/parser/common.py +266 -0
  195. dbt/parser/docs.py +52 -0
  196. dbt/parser/fixtures.py +51 -0
  197. dbt/parser/functions.py +30 -0
  198. dbt/parser/generic_test.py +100 -0
  199. dbt/parser/generic_test_builders.py +333 -0
  200. dbt/parser/hooks.py +118 -0
  201. dbt/parser/macros.py +137 -0
  202. dbt/parser/manifest.py +2204 -0
  203. dbt/parser/models.py +573 -0
  204. dbt/parser/partial.py +1178 -0
  205. dbt/parser/read_files.py +445 -0
  206. dbt/parser/schema_generic_tests.py +422 -0
  207. dbt/parser/schema_renderer.py +111 -0
  208. dbt/parser/schema_yaml_readers.py +935 -0
  209. dbt/parser/schemas.py +1466 -0
  210. dbt/parser/search.py +149 -0
  211. dbt/parser/seeds.py +28 -0
  212. dbt/parser/singular_test.py +20 -0
  213. dbt/parser/snapshots.py +44 -0
  214. dbt/parser/sources.py +558 -0
  215. dbt/parser/sql.py +62 -0
  216. dbt/parser/unit_tests.py +621 -0
  217. dbt/plugins/__init__.py +20 -0
  218. dbt/plugins/contracts.py +9 -0
  219. dbt/plugins/exceptions.py +2 -0
  220. dbt/plugins/manager.py +163 -0
  221. dbt/plugins/manifest.py +21 -0
  222. dbt/profiler.py +20 -0
  223. dbt/py.typed +1 -0
  224. dbt/query_analyzer.cpython-310-darwin.so +0 -0
  225. dbt/query_analyzer.py +410 -0
  226. dbt/runners/__init__.py +2 -0
  227. dbt/runners/exposure_runner.py +7 -0
  228. dbt/runners/no_op_runner.py +45 -0
  229. dbt/runners/saved_query_runner.py +7 -0
  230. dbt/selected_resources.py +8 -0
  231. dbt/task/__init__.py +0 -0
  232. dbt/task/base.py +503 -0
  233. dbt/task/build.py +197 -0
  234. dbt/task/clean.py +56 -0
  235. dbt/task/clone.py +161 -0
  236. dbt/task/compile.py +150 -0
  237. dbt/task/compute.py +454 -0
  238. dbt/task/debug.py +505 -0
  239. dbt/task/deps.py +280 -0
  240. dbt/task/docs/__init__.py +3 -0
  241. dbt/task/docs/generate.py +660 -0
  242. dbt/task/docs/index.html +250 -0
  243. dbt/task/docs/serve.py +29 -0
  244. dbt/task/freshness.py +322 -0
  245. dbt/task/function.py +121 -0
  246. dbt/task/group_lookup.py +46 -0
  247. dbt/task/init.py +553 -0
  248. dbt/task/java.py +316 -0
  249. dbt/task/list.py +236 -0
  250. dbt/task/printer.py +175 -0
  251. dbt/task/retry.py +175 -0
  252. dbt/task/run.py +1306 -0
  253. dbt/task/run_operation.py +141 -0
  254. dbt/task/runnable.py +758 -0
  255. dbt/task/seed.py +103 -0
  256. dbt/task/show.py +149 -0
  257. dbt/task/snapshot.py +56 -0
  258. dbt/task/spark.py +414 -0
  259. dbt/task/sql.py +110 -0
  260. dbt/task/target_sync.py +759 -0
  261. dbt/task/test.py +464 -0
  262. dbt/tests/fixtures/__init__.py +1 -0
  263. dbt/tests/fixtures/project.py +620 -0
  264. dbt/tests/util.py +651 -0
  265. dbt/tracking.py +529 -0
  266. dbt/utils/__init__.py +3 -0
  267. dbt/utils/artifact_upload.py +151 -0
  268. dbt/utils/utils.py +408 -0
  269. dbt/version.py +268 -0
  270. dvt_cli/__init__.py +72 -0
  271. dvt_core-0.52.2.dist-info/METADATA +286 -0
  272. dvt_core-0.52.2.dist-info/RECORD +275 -0
  273. dvt_core-0.52.2.dist-info/WHEEL +5 -0
  274. dvt_core-0.52.2.dist-info/entry_points.txt +2 -0
  275. dvt_core-0.52.2.dist-info/top_level.txt +2 -0
dbt/links.py ADDED
@@ -0,0 +1,4 @@
1
+ ProfileConfigDocs = "https://docs.getdbt.com/docs/configure-your-profile"
2
+ SnowflakeQuotingDocs = "https://docs.getdbt.com/v0.10/docs/configuring-quoting"
3
+ IncrementalDocs = "https://docs.getdbt.com/docs/configuring-incremental-models"
4
+ BigQueryNewPartitionBy = "https://docs.getdbt.com/docs/upgrading-to-0-16-0"
File without changes
File without changes
@@ -0,0 +1,236 @@
1
+ from datetime import datetime, timedelta
2
+ from typing import Any, Dict, List, Optional
3
+
4
+ import pytz
5
+
6
+ from dbt.artifacts.resources.types import BatchSize
7
+ from dbt.artifacts.schemas.batch_results import BatchType
8
+ from dbt.contracts.graph.nodes import ModelNode, NodeConfig
9
+ from dbt.exceptions import DbtInternalError, DbtRuntimeError
10
+
11
+
12
+ class MicrobatchBuilder:
13
+ """A utility class for building microbatch definitions associated with a specific model"""
14
+
15
+ def __init__(
16
+ self,
17
+ model: ModelNode,
18
+ is_incremental: bool,
19
+ event_time_start: Optional[datetime],
20
+ event_time_end: Optional[datetime],
21
+ default_end_time: Optional[datetime] = None,
22
+ ):
23
+ if model.config.incremental_strategy != "microbatch":
24
+ raise DbtInternalError(
25
+ f"Model '{model.name}' does not use 'microbatch' incremental_strategy."
26
+ )
27
+ self.model = model
28
+
29
+ if self.model.config.batch_size is None:
30
+ raise DbtRuntimeError(
31
+ f"Microbatch model '{self.model.name}' does not have a 'batch_size' config (one of {[batch_size.value for batch_size in BatchSize]}) specificed."
32
+ )
33
+
34
+ self.is_incremental = is_incremental
35
+ self.event_time_start = (
36
+ event_time_start.replace(tzinfo=pytz.UTC) if event_time_start else None
37
+ )
38
+ self.event_time_end = event_time_end.replace(tzinfo=pytz.UTC) if event_time_end else None
39
+ self.default_end_time = default_end_time or datetime.now(pytz.UTC)
40
+
41
+ def build_end_time(self):
42
+ """Defaults the end_time to the current time in UTC unless a non `None` event_time_end was provided"""
43
+ end_time = self.event_time_end or self.default_end_time
44
+ return MicrobatchBuilder.ceiling_timestamp(end_time, self.model.config.batch_size)
45
+
46
+ def build_start_time(self, checkpoint: Optional[datetime]):
47
+ """Create a start time based off the passed in checkpoint.
48
+
49
+ If the checkpoint is `None`, or this is the first run of a microbatch model, then the
50
+ model's configured `begin` value will be returned as a checkpoint is necessary
51
+ to build a start time. This is because we build the start time relative to the checkpoint
52
+ via the batchsize and offset, and we cannot offset a checkpoint if there is no checkpoint.
53
+ """
54
+ assert isinstance(self.model.config, NodeConfig)
55
+ batch_size = self.model.config.batch_size
56
+
57
+ # Use event_time_start if it is provided.
58
+ if self.event_time_start:
59
+ return MicrobatchBuilder.truncate_timestamp(self.event_time_start, batch_size)
60
+
61
+ # First run, use model's configured 'begin' as start.
62
+ if not self.is_incremental or checkpoint is None:
63
+ if not self.model.config.begin:
64
+ raise DbtRuntimeError(
65
+ f"Microbatch model '{self.model.name}' requires a 'begin' configuration."
66
+ )
67
+
68
+ return MicrobatchBuilder.truncate_timestamp(self.model.config.begin, batch_size)
69
+
70
+ lookback = self.model.config.lookback
71
+
72
+ # If the checkpoint is equivalent to itself truncated then the checkpoint stradles
73
+ # the batch line. In this case the last batch will end with the checkpoint, but start
74
+ # should be the previous hour/day/month/year. Thus we need to increase the lookback by
75
+ # 1 to get this affect properly.
76
+ if checkpoint == MicrobatchBuilder.truncate_timestamp(checkpoint, batch_size):
77
+ lookback += 1
78
+
79
+ return MicrobatchBuilder.offset_timestamp(checkpoint, batch_size, -1 * lookback)
80
+
81
+ def build_batches(self, start: datetime, end: datetime) -> List[BatchType]:
82
+ """
83
+ Given a start and end datetime, builds a list of batches where each batch is
84
+ the size of the model's batch_size.
85
+ """
86
+ batch_size = self.model.config.batch_size
87
+ curr_batch_start: datetime = start
88
+ curr_batch_end: datetime = MicrobatchBuilder.offset_timestamp(
89
+ curr_batch_start, batch_size, 1
90
+ )
91
+
92
+ batches: List[BatchType] = [(curr_batch_start, curr_batch_end)]
93
+ while curr_batch_end < end:
94
+ curr_batch_start = curr_batch_end
95
+ curr_batch_end = MicrobatchBuilder.offset_timestamp(curr_batch_start, batch_size, 1)
96
+ batches.append((curr_batch_start, curr_batch_end))
97
+
98
+ # use exact end value as stop
99
+ batches[-1] = (batches[-1][0], end)
100
+
101
+ return batches
102
+
103
+ @staticmethod
104
+ def build_jinja_context_for_batch(model: ModelNode, incremental_batch: bool) -> Dict[str, Any]:
105
+ """
106
+ Create context with entries that reflect microbatch model + incremental execution state
107
+
108
+ Assumes self.model has been (re)-compiled with necessary batch filters applied.
109
+ """
110
+ jinja_context: Dict[str, Any] = {}
111
+
112
+ # Microbatch model properties
113
+ jinja_context["model"] = model.to_dict()
114
+ jinja_context["sql"] = model.compiled_code
115
+ jinja_context["compiled_code"] = model.compiled_code
116
+
117
+ # Add incremental context variables for batches running incrementally
118
+ if incremental_batch:
119
+ jinja_context["is_incremental"] = lambda: True
120
+ jinja_context["should_full_refresh"] = lambda: False
121
+
122
+ return jinja_context
123
+
124
+ @staticmethod
125
+ def offset_timestamp(timestamp: datetime, batch_size: BatchSize, offset: int) -> datetime:
126
+ """Truncates the passed in timestamp based on the batch_size and then applies the offset by the batch_size.
127
+
128
+ Note: It's important to understand that the offset applies to the truncated timestamp, not
129
+ the origin timestamp. Thus being offset by a day isn't relative to the any given hour that day,
130
+ but relative to the start of the day. So if the timestamp is the very end of a day, 2024-09-17 23:59:59,
131
+ you have a batch size of a day, and an offset of +1, then the returned value ends up being only one
132
+ second later, 2024-09-18 00:00:00.
133
+
134
+ 2024-09-17 16:06:00 + Batchsize.hour -1 -> 2024-09-17 15:00:00
135
+ 2024-09-17 16:06:00 + Batchsize.hour +1 -> 2024-09-17 17:00:00
136
+ 2024-09-17 16:06:00 + Batchsize.day -1 -> 2024-09-16 00:00:00
137
+ 2024-09-17 16:06:00 + Batchsize.day +1 -> 2024-09-18 00:00:00
138
+ 2024-09-17 16:06:00 + Batchsize.month -1 -> 2024-08-01 00:00:00
139
+ 2024-09-17 16:06:00 + Batchsize.month +1 -> 2024-10-01 00:00:00
140
+ 2024-09-17 16:06:00 + Batchsize.year -1 -> 2023-01-01 00:00:00
141
+ 2024-09-17 16:06:00 + Batchsize.year +1 -> 2025-01-01 00:00:00
142
+ """
143
+ truncated = MicrobatchBuilder.truncate_timestamp(timestamp, batch_size)
144
+
145
+ offset_timestamp: datetime
146
+ if batch_size == BatchSize.hour:
147
+ offset_timestamp = truncated + timedelta(hours=offset)
148
+ elif batch_size == BatchSize.day:
149
+ offset_timestamp = truncated + timedelta(days=offset)
150
+ elif batch_size == BatchSize.month:
151
+ offset_timestamp = truncated
152
+ for _ in range(abs(offset)):
153
+ if offset < 0:
154
+ offset_timestamp = offset_timestamp - timedelta(days=1)
155
+ else:
156
+ offset_timestamp = offset_timestamp + timedelta(days=31)
157
+ offset_timestamp = MicrobatchBuilder.truncate_timestamp(
158
+ offset_timestamp, batch_size
159
+ )
160
+ elif batch_size == BatchSize.year:
161
+ offset_timestamp = truncated.replace(year=truncated.year + offset)
162
+
163
+ return offset_timestamp
164
+
165
+ @staticmethod
166
+ def truncate_timestamp(timestamp: datetime, batch_size: BatchSize) -> datetime:
167
+ """Truncates the passed in timestamp based on the batch_size.
168
+
169
+ 2024-09-17 16:06:00 + Batchsize.hour -> 2024-09-17 16:00:00
170
+ 2024-09-17 16:06:00 + Batchsize.day -> 2024-09-17 00:00:00
171
+ 2024-09-17 16:06:00 + Batchsize.month -> 2024-09-01 00:00:00
172
+ 2024-09-17 16:06:00 + Batchsize.year -> 2024-01-01 00:00:00
173
+ """
174
+ if batch_size == BatchSize.hour:
175
+ truncated = datetime(
176
+ timestamp.year,
177
+ timestamp.month,
178
+ timestamp.day,
179
+ timestamp.hour,
180
+ 0,
181
+ 0,
182
+ 0,
183
+ pytz.utc,
184
+ )
185
+ elif batch_size == BatchSize.day:
186
+ truncated = datetime(
187
+ timestamp.year, timestamp.month, timestamp.day, 0, 0, 0, 0, pytz.utc
188
+ )
189
+ elif batch_size == BatchSize.month:
190
+ truncated = datetime(timestamp.year, timestamp.month, 1, 0, 0, 0, 0, pytz.utc)
191
+ elif batch_size == BatchSize.year:
192
+ truncated = datetime(timestamp.year, 1, 1, 0, 0, 0, 0, pytz.utc)
193
+
194
+ return truncated
195
+
196
+ @staticmethod
197
+ def batch_id(start_time: datetime, batch_size: BatchSize) -> str:
198
+ return MicrobatchBuilder.format_batch_start(start_time, batch_size).replace("-", "")
199
+
200
+ @staticmethod
201
+ def format_batch_start(batch_start: datetime, batch_size: BatchSize) -> str:
202
+ """Format the passed in datetime based on the batch_size.
203
+
204
+ 2024-09-17 16:06:00 + Batchsize.hour -> 2024-09-17T16
205
+ 2024-09-17 16:06:00 + Batchsize.day -> 2024-09-17
206
+ 2024-09-17 16:06:00 + Batchsize.month -> 2024-09
207
+ 2024-09-17 16:06:00 + Batchsize.year -> 2024
208
+ """
209
+ if batch_size == BatchSize.year:
210
+ return batch_start.strftime("%Y")
211
+ elif batch_size == BatchSize.month:
212
+ return batch_start.strftime("%Y-%m")
213
+ elif batch_size == BatchSize.day:
214
+ return batch_start.strftime("%Y-%m-%d")
215
+ else: # batch_size == BatchSize.hour
216
+ return batch_start.strftime("%Y-%m-%dT%H")
217
+
218
+ @staticmethod
219
+ def ceiling_timestamp(timestamp: datetime, batch_size: BatchSize) -> datetime:
220
+ """Takes the given timestamp and moves it to the ceiling for the given batch size
221
+
222
+ Note, if the timestamp is already the batch size ceiling, that is returned
223
+ 2024-09-17 16:06:00 + BatchSize.hour -> 2024-09-17 17:00:00
224
+ 2024-09-17 16:00:00 + BatchSize.hour -> 2024-09-17 16:00:00
225
+ 2024-09-17 16:06:00 + BatchSize.day -> 2024-09-18 00:00:00
226
+ 2024-09-17 00:00:00 + BatchSize.day -> 2024-09-17 00:00:00
227
+ 2024-09-17 16:06:00 + BatchSize.month -> 2024-10-01 00:00:00
228
+ 2024-09-01 00:00:00 + BatchSize.month -> 2024-09-01 00:00:00
229
+ 2024-09-17 16:06:00 + BatchSize.year -> 2025-01-01 00:00:00
230
+ 2024-01-01 00:00:00 + BatchSize.year -> 2024-01-01 00:00:00
231
+
232
+ """
233
+ ceiling = truncated = MicrobatchBuilder.truncate_timestamp(timestamp, batch_size)
234
+ if truncated != timestamp:
235
+ ceiling = MicrobatchBuilder.offset_timestamp(truncated, batch_size, 1)
236
+ return ceiling
dbt/mp_context.py ADDED
@@ -0,0 +1,8 @@
1
+ from multiprocessing import get_context
2
+ from multiprocessing.context import SpawnContext
3
+
4
+ _MP_CONTEXT = get_context("spawn")
5
+
6
+
7
+ def get_mp_context() -> SpawnContext:
8
+ return _MP_CONTEXT
dbt/node_types.py ADDED
@@ -0,0 +1,37 @@
1
+ from typing import List
2
+
3
+ # preserving import path during dbt/artifacts refactor
4
+ from dbt.artifacts.resources.types import ( # noqa
5
+ AccessType,
6
+ ModelLanguage,
7
+ NodeType,
8
+ RunHookType,
9
+ )
10
+
11
+ EXECUTABLE_NODE_TYPES: List["NodeType"] = [
12
+ NodeType.Model,
13
+ NodeType.Test,
14
+ NodeType.Snapshot,
15
+ NodeType.Analysis,
16
+ NodeType.Operation,
17
+ NodeType.Seed,
18
+ NodeType.Documentation,
19
+ NodeType.RPCCall,
20
+ NodeType.SqlOperation,
21
+ NodeType.Function,
22
+ ]
23
+
24
+ REFABLE_NODE_TYPES: List["NodeType"] = [
25
+ NodeType.Model,
26
+ NodeType.Seed,
27
+ NodeType.Snapshot,
28
+ ]
29
+
30
+ TEST_NODE_TYPES: List["NodeType"] = [
31
+ NodeType.Test,
32
+ NodeType.Unit,
33
+ ]
34
+
35
+ VERSIONED_NODE_TYPES: List["NodeType"] = [
36
+ NodeType.Model,
37
+ ]
dbt/parser/__init__.py ADDED
@@ -0,0 +1,23 @@
1
+ from . import ( # noqa
2
+ analysis,
3
+ base,
4
+ docs,
5
+ generic_test,
6
+ hooks,
7
+ macros,
8
+ models,
9
+ schemas,
10
+ singular_test,
11
+ snapshots,
12
+ )
13
+ from .analysis import AnalysisParser # noqa
14
+ from .base import ConfiguredParser, Parser # noqa
15
+ from .docs import DocumentationParser # noqa
16
+ from .generic_test import GenericTestParser # noqa
17
+ from .hooks import HookParser # noqa
18
+ from .macros import MacroParser # noqa
19
+ from .models import ModelParser # noqa
20
+ from .schemas import SchemaParser # noqa
21
+ from .seeds import SeedParser # noqa
22
+ from .singular_test import SingularTestParser # noqa
23
+ from .snapshots import SnapshotParser # noqa
dbt/parser/analysis.py ADDED
@@ -0,0 +1,21 @@
1
+ import os
2
+
3
+ from dbt.contracts.graph.nodes import AnalysisNode
4
+ from dbt.node_types import NodeType
5
+ from dbt.parser.base import SimpleSQLParser
6
+ from dbt.parser.search import FileBlock
7
+
8
+
9
+ class AnalysisParser(SimpleSQLParser[AnalysisNode]):
10
+ def parse_from_dict(self, dct, validate=True) -> AnalysisNode:
11
+ if validate:
12
+ AnalysisNode.validate(dct)
13
+ return AnalysisNode.from_dict(dct)
14
+
15
+ @property
16
+ def resource_type(self) -> NodeType:
17
+ return NodeType.Analysis
18
+
19
+ @classmethod
20
+ def get_compiled_path(cls, block: FileBlock):
21
+ return os.path.join("analysis", block.path.relative_path)