dbt-common 1.1.0__tar.gz → 1.3.0__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 (105) hide show
  1. {dbt_common-1.1.0 → dbt_common-1.3.0}/.gitignore +1 -1
  2. {dbt_common-1.1.0 → dbt_common-1.3.0}/PKG-INFO +1 -1
  3. dbt_common-1.3.0/dbt_common/__about__.py +1 -0
  4. dbt_common-1.3.0/dbt_common/contracts/metadata.py +59 -0
  5. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/record.py +42 -7
  6. {dbt_common-1.1.0 → dbt_common-1.3.0}/docs/guides/record_replay.md +16 -1
  7. dbt_common-1.1.0/dbt_common/__about__.py +0 -1
  8. {dbt_common-1.1.0 → dbt_common-1.3.0}/CHANGELOG.md +0 -0
  9. {dbt_common-1.1.0 → dbt_common-1.3.0}/LICENSE +0 -0
  10. {dbt_common-1.1.0 → dbt_common-1.3.0}/README.md +0 -0
  11. {dbt_common-1.1.0 → dbt_common-1.3.0}/codecov.yml +0 -0
  12. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/__init__.py +0 -0
  13. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/clients/__init__.py +0 -0
  14. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/clients/_jinja_blocks.py +0 -0
  15. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/clients/agate_helper.py +0 -0
  16. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/clients/jinja.py +0 -0
  17. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/clients/system.py +0 -0
  18. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/constants.py +0 -0
  19. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/context.py +0 -0
  20. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/contracts/__init__.py +0 -0
  21. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/contracts/config/__init__.py +0 -0
  22. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/contracts/config/base.py +0 -0
  23. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/contracts/config/materialization.py +0 -0
  24. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/contracts/config/metadata.py +0 -0
  25. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/contracts/config/properties.py +0 -0
  26. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/contracts/constraints.py +0 -0
  27. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/contracts/util.py +0 -0
  28. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/dataclass_schema.py +0 -0
  29. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/README.md +0 -0
  30. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/__init__.py +0 -0
  31. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/base_types.py +0 -0
  32. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/contextvars.py +0 -0
  33. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/event_handler.py +0 -0
  34. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/event_manager.py +0 -0
  35. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/event_manager_client.py +0 -0
  36. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/format.py +0 -0
  37. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/functions.py +0 -0
  38. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/helpers.py +0 -0
  39. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/interfaces.py +0 -0
  40. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/logger.py +0 -0
  41. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/types.proto +0 -0
  42. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/types.py +0 -0
  43. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/events/types_pb2.py +0 -0
  44. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/__init__.py +0 -0
  45. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/base.py +0 -0
  46. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/cache.py +0 -0
  47. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/connection.py +0 -0
  48. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/contracts.py +0 -0
  49. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/events.py +0 -0
  50. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/jinja.py +0 -0
  51. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/macros.py +0 -0
  52. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/exceptions/system.py +0 -0
  53. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/helper_types.py +0 -0
  54. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/invocation.py +0 -0
  55. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/py.typed +0 -0
  56. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/semver.py +0 -0
  57. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/tests.py +0 -0
  58. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/ui.py +0 -0
  59. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/utils/__init__.py +0 -0
  60. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/utils/casting.py +0 -0
  61. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/utils/connection.py +0 -0
  62. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/utils/dict.py +0 -0
  63. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/utils/encoding.py +0 -0
  64. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/utils/executor.py +0 -0
  65. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/utils/formatting.py +0 -0
  66. {dbt_common-1.1.0 → dbt_common-1.3.0}/dbt_common/utils/jinja.py +0 -0
  67. {dbt_common-1.1.0 → dbt_common-1.3.0}/docs/README.md +0 -0
  68. {dbt_common-1.1.0 → dbt_common-1.3.0}/docs/arch/adr-0001-build-tooling.md +0 -0
  69. {dbt_common-1.1.0 → dbt_common-1.3.0}/pyproject.toml +0 -0
  70. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/agate/__init__.pyi +0 -0
  71. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/agate/data_types.pyi +0 -0
  72. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/colorama/__init__.pyi +0 -0
  73. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/isodate/__init__.pyi +0 -0
  74. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/__init__.pyi +0 -0
  75. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/config.pyi +0 -0
  76. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/__init__.pyi +0 -0
  77. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/const.pyi +0 -0
  78. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/helpers.pyi +0 -0
  79. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/__init__.pyi +0 -0
  80. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/code/__init__.pyi +0 -0
  81. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/code/builder.pyi +0 -0
  82. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/code/lines.pyi +0 -0
  83. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/helpers.pyi +0 -0
  84. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/mixin.pyi +0 -0
  85. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/types/__init__.pyi +0 -0
  86. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/types/common.pyi +0 -0
  87. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/types/pack.pyi +0 -0
  88. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/core/meta/types/unpack.pyi +0 -0
  89. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/dialect.pyi +0 -0
  90. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/exceptions.pyi +0 -0
  91. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/helper.pyi +0 -0
  92. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/jsonschema/__init__.pyi +0 -0
  93. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/jsonschema/annotations.pyi +0 -0
  94. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/jsonschema/builder.pyi +0 -0
  95. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/jsonschema/dialects.pyi +0 -0
  96. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/jsonschema/models.pyi +0 -0
  97. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/jsonschema/schema.pyi +0 -0
  98. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/mixins/__init__.pyi +0 -0
  99. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/mixins/dict.pyi +0 -0
  100. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/mixins/json.pyi +0 -0
  101. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/mixins/msgpack.pyi +0 -0
  102. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/mixins/orjson.pyi +0 -0
  103. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/mixins/toml.pyi +0 -0
  104. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/mixins/yaml.pyi +0 -0
  105. {dbt_common-1.1.0 → dbt_common-1.3.0}/third-party-stubs/mashumaro/types.pyi +0 -0
@@ -157,4 +157,4 @@ cython_debug/
157
157
  # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158
158
  # and can be added to the global gitignore or merged into this file. For a more nuclear
159
159
  # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
- #.idea/
160
+ .idea/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dbt-common
3
- Version: 1.1.0
3
+ Version: 1.3.0
4
4
  Summary: The shared common utilities that dbt-core and adapter implementations use
5
5
  Project-URL: Homepage, https://github.com/dbt-labs/dbt-common
6
6
  Project-URL: Repository, https://github.com/dbt-labs/dbt-common.git
@@ -0,0 +1 @@
1
+ version = "1.3.0"
@@ -0,0 +1,59 @@
1
+ from dataclasses import dataclass
2
+ from typing import Dict, Optional, Union, NamedTuple
3
+
4
+ from dbt_common.dataclass_schema import dbtClassMixin
5
+ from dbt_common.utils.formatting import lowercase
6
+
7
+
8
+ @dataclass
9
+ class StatsItem(dbtClassMixin):
10
+ id: str
11
+ label: str
12
+ value: Union[bool, str, float, None]
13
+ include: bool
14
+ description: Optional[str] = None
15
+
16
+
17
+ StatsDict = Dict[str, StatsItem]
18
+
19
+
20
+ @dataclass
21
+ class TableMetadata(dbtClassMixin):
22
+ type: str
23
+ schema: str
24
+ name: str
25
+ database: Optional[str] = None
26
+ comment: Optional[str] = None
27
+ owner: Optional[str] = None
28
+
29
+
30
+ CatalogKey = NamedTuple(
31
+ "CatalogKey", [("database", Optional[str]), ("schema", str), ("name", str)]
32
+ )
33
+
34
+
35
+ @dataclass
36
+ class ColumnMetadata(dbtClassMixin):
37
+ type: str
38
+ index: int
39
+ name: str
40
+ comment: Optional[str] = None
41
+
42
+
43
+ ColumnMap = Dict[str, ColumnMetadata]
44
+
45
+
46
+ @dataclass
47
+ class CatalogTable(dbtClassMixin):
48
+ metadata: TableMetadata
49
+ columns: ColumnMap
50
+ stats: StatsDict
51
+ # the same table with two unique IDs will just be listed two times
52
+ unique_id: Optional[str] = None
53
+
54
+ def key(self) -> CatalogKey:
55
+ return CatalogKey(
56
+ lowercase(self.metadata.database),
57
+ self.metadata.schema.lower(),
58
+ self.metadata.name.lower(),
59
+ )
@@ -59,14 +59,18 @@ class Diff:
59
59
  class RecorderMode(Enum):
60
60
  RECORD = 1
61
61
  REPLAY = 2
62
+ RECORD_QUERIES = 3
62
63
 
63
64
 
64
65
  class Recorder:
65
66
  _record_cls_by_name: Dict[str, Type] = {}
66
67
  _record_name_by_params_name: Dict[str, str] = {}
67
68
 
68
- def __init__(self, mode: RecorderMode, recording_path: Optional[str] = None) -> None:
69
+ def __init__(
70
+ self, mode: RecorderMode, types: Optional[List], recording_path: Optional[str] = None
71
+ ) -> None:
69
72
  self.mode = mode
73
+ self.types = types
70
74
  self._records_by_type: Dict[str, List[Record]] = {}
71
75
  self._replay_diffs: List["Diff"] = []
72
76
 
@@ -118,13 +122,14 @@ class Recorder:
118
122
  records_by_type: Dict[str, List[Record]] = {}
119
123
 
120
124
  for record_type_name in loaded_dct:
125
+ # TODO: this breaks with QueryRecord on replay since it's
126
+ # not in common so isn't part of cls._record_cls_by_name yet
121
127
  record_cls = cls._record_cls_by_name[record_type_name]
122
128
  rec_list = []
123
129
  for record_dct in loaded_dct[record_type_name]:
124
130
  rec = record_cls.from_dict(record_dct)
125
131
  rec_list.append(rec) # type: ignore
126
132
  records_by_type[record_type_name] = rec_list
127
-
128
133
  return records_by_type
129
134
 
130
135
  def expect_record(self, params: Any) -> Any:
@@ -147,17 +152,44 @@ class Recorder:
147
152
 
148
153
 
149
154
  def get_record_mode_from_env() -> Optional[RecorderMode]:
150
- replay_val = os.environ.get("DBT_REPLAY")
151
- if replay_val is not None and replay_val != "0" and replay_val.lower() != "false":
152
- return RecorderMode.REPLAY
155
+ """
156
+ Get the record mode from the environment variables.
157
+
158
+ If the mode is not set to 'RECORD' or 'REPLAY', return None.
159
+ Expected format: 'DBT_RECORDER_MODE=RECORD'
160
+ """
161
+ record_mode = os.environ.get("DBT_RECORDER_MODE")
153
162
 
154
- record_val = os.environ.get("DBT_RECORD")
155
- if record_val is not None and record_val != "0" and record_val.lower() != "false":
163
+ if record_mode is None:
164
+ return None
165
+
166
+ if record_mode.lower() == "record":
156
167
  return RecorderMode.RECORD
168
+ # replaying requires a file path, otherwise treat as noop
169
+ elif record_mode.lower() == "replay" and os.environ.get("DBT_RECORDER_FILE_PATH") is not None:
170
+ return RecorderMode.REPLAY
157
171
 
172
+ # if you don't specify record/replay it's a noop
158
173
  return None
159
174
 
160
175
 
176
+ def get_record_types_from_env() -> Optional[List]:
177
+ """
178
+ Get the record subset from the environment variables.
179
+
180
+ If no types are provided, there will be no filtering.
181
+ Invalid types will be ignored.
182
+ Expected format: 'DBT_RECORDER_TYPES=QueryRecord,FileLoadRecord,OtherRecord'
183
+ """
184
+ record_types_str = os.environ.get("DBT_RECORDER_TYPES")
185
+
186
+ # if all is specified we don't want any type filtering
187
+ if record_types_str is None or record_types_str.lower == "all":
188
+ return None
189
+
190
+ return record_types_str.split(",")
191
+
192
+
161
193
  def record_function(record_type, method=False, tuple_result=False):
162
194
  def record_function_inner(func_to_record):
163
195
  # To avoid runtime overhead and other unpleasantness, we only apply the
@@ -176,6 +208,9 @@ def record_function(record_type, method=False, tuple_result=False):
176
208
  if recorder is None:
177
209
  return func_to_record(*args, **kwargs)
178
210
 
211
+ if recorder.types is not None and record_type.__name__ not in recorder.types:
212
+ return func_to_record(*args, **kwargs)
213
+
179
214
  # For methods, peel off the 'self' argument before calling the
180
215
  # params constructor.
181
216
  param_args = args[1:] if method else args
@@ -28,7 +28,22 @@ Note also the `LoadFileRecord` class passed as a parameter to this decorator. Th
28
28
 
29
29
  The final detail needed is to define the classes specified by `params_cls` and `result_cls`, which must be dataclasses with properties whose order and names correspond to the parameters passed to the recorded function. In this case those are the `LoadFileParams` and `LoadFileResult` classes, respectively.
30
30
 
31
- With these decorators applied and classes defined, dbt is able to record all file access during a run, and mock out the accesses during replay, isolating dbt from actually loading files. At least it would if dbt only used this function for all file access, which is only mostly true. We hope to continue improving the usefulness of this mechanism by adding more recorded functions and routing more operations through them.
31
+ With these decorators applied and classes defined, dbt is able to record all file access during a run, and mock out the accesses during replay, isolating dbt from actually loading files. At least it would if dbt only used this function for all file access, which is only mostly true. We hope to continue improving the usefulness of this mechanism by adding more recorded functions and routing more operations through them.
32
+
33
+ ## How to record/replay
34
+ If `DBT_RECORDER_MODE` is not `replay` or `record`, case insensitive, this is a no-op. Invalid values are ignored and do not throw exceptions.
35
+
36
+ `DBT_RECODER_TYPES` is optional. It indicates which types to filter the results by and expects a list of strings values for the `Record` subclasses. Any invalid types will be ignored. `all` is a valid type and behaves the same as not populating the env var.
37
+
38
+
39
+ ```bash
40
+ DBT_RECORDER_MODE=record DBT_RECODER_TYPES=QueryRecord,GetEnvRecord dbt run
41
+ ```
42
+
43
+ replay need the file to replay
44
+ ```bash
45
+ DBT_RECORDER_MODE=replay DBT_RECORDER_FILE_PATH=recording.json dbt run
46
+ ```
32
47
 
33
48
  ## Final Thoughts
34
49
 
@@ -1 +0,0 @@
1
- version = "1.1.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes