dbt-common 0.1.1__py3-none-any.whl → 0.1.5__py3-none-any.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.
- dbt_common/__about__.py +1 -1
- dbt_common/clients/_jinja_blocks.py +29 -9
- dbt_common/clients/agate_helper.py +32 -23
- dbt_common/clients/jinja.py +74 -26
- dbt_common/clients/system.py +43 -25
- dbt_common/context.py +48 -0
- dbt_common/contracts/config/base.py +12 -4
- dbt_common/contracts/constraints.py +6 -2
- dbt_common/contracts/util.py +16 -0
- dbt_common/dataclass_schema.py +3 -1
- dbt_common/events/__init__.py +3 -1
- dbt_common/events/base_types.py +7 -4
- dbt_common/events/event_handler.py +2 -1
- dbt_common/events/event_manager.py +5 -2
- dbt_common/events/format.py +3 -1
- dbt_common/events/functions.py +18 -12
- dbt_common/events/logger.py +13 -9
- dbt_common/events/types.py +5 -2
- dbt_common/events/types_pb2.py +49 -53
- dbt_common/exceptions/base.py +11 -7
- dbt_common/exceptions/cache.py +7 -2
- dbt_common/exceptions/connection.py +4 -3
- dbt_common/exceptions/jinja.py +2 -1
- dbt_common/exceptions/macros.py +10 -5
- dbt_common/helper_types.py +10 -4
- dbt_common/semver.py +26 -8
- dbt_common/tests.py +15 -0
- dbt_common/ui.py +2 -1
- dbt_common/utils/connection.py +3 -1
- dbt_common/utils/dict.py +13 -6
- dbt_common/utils/encoding.py +4 -2
- dbt_common/utils/executor.py +19 -3
- {dbt_common-0.1.1.dist-info → dbt_common-0.1.5.dist-info}/METADATA +33 -2
- dbt_common-0.1.5.dist-info/RECORD +60 -0
- dbt_common-0.1.1.dist-info/RECORD +0 -58
- {dbt_common-0.1.1.dist-info → dbt_common-0.1.5.dist-info}/WHEEL +0 -0
- {dbt_common-0.1.1.dist-info → dbt_common-0.1.5.dist-info}/licenses/LICENSE +0 -0
@@ -38,7 +38,9 @@ class BaseConfig(AdditionalPropertiesAllowed, Replaceable):
|
|
38
38
|
|
39
39
|
def __delitem__(self, key):
|
40
40
|
if hasattr(self, key):
|
41
|
-
msg = (
|
41
|
+
msg = (
|
42
|
+
'Error, tried to delete config key "{}": Cannot delete ' "built-in keys"
|
43
|
+
).format(key)
|
42
44
|
raise CompilationError(msg)
|
43
45
|
else:
|
44
46
|
del self._extra[key]
|
@@ -110,7 +112,9 @@ class BaseConfig(AdditionalPropertiesAllowed, Replaceable):
|
|
110
112
|
|
111
113
|
@classmethod
|
112
114
|
def _merge_dicts(cls, src: Dict[str, Any], data: Dict[str, Any]) -> Dict[str, Any]:
|
113
|
-
"""
|
115
|
+
"""Mutate input to return merge results.
|
116
|
+
|
117
|
+
Find all the items in data that match a target_field on this class,
|
114
118
|
and merge them with the data found in `src` for target_field, using the
|
115
119
|
field's specified merge behavior. Matching items will be removed from
|
116
120
|
`data` (but _not_ `src`!).
|
@@ -141,8 +145,12 @@ class BaseConfig(AdditionalPropertiesAllowed, Replaceable):
|
|
141
145
|
)
|
142
146
|
return result
|
143
147
|
|
144
|
-
def update_from(
|
145
|
-
|
148
|
+
def update_from(
|
149
|
+
self: T, data: Dict[str, Any], config_cls: Type[BaseConfig], validate: bool = True
|
150
|
+
) -> T:
|
151
|
+
"""Update and validate config given a dict.
|
152
|
+
|
153
|
+
Given a dict of keys, update the current config from them, validate
|
146
154
|
it, and return a new config with the updated values
|
147
155
|
"""
|
148
156
|
dct = self.to_dict(omit_none=False)
|
@@ -30,8 +30,12 @@ class ColumnLevelConstraint(dbtClassMixin):
|
|
30
30
|
# It could be a predicate (check type), or a sequence sql keywords (e.g. unique type),
|
31
31
|
# so the vague naming of 'expression' is intended to capture this range.
|
32
32
|
expression: Optional[str] = None
|
33
|
-
warn_unenforced: bool =
|
34
|
-
|
33
|
+
warn_unenforced: bool = (
|
34
|
+
True # Warn if constraint cannot be enforced by platform but will be in DDL
|
35
|
+
)
|
36
|
+
warn_unsupported: bool = (
|
37
|
+
True # Warn if constraint is not supported by the platform and won't be in DDL
|
38
|
+
)
|
35
39
|
|
36
40
|
|
37
41
|
@dataclass
|
dbt_common/contracts/util.py
CHANGED
@@ -5,3 +5,19 @@ import dataclasses
|
|
5
5
|
class Replaceable:
|
6
6
|
def replace(self, **kwargs):
|
7
7
|
return dataclasses.replace(self, **kwargs)
|
8
|
+
|
9
|
+
|
10
|
+
class Mergeable(Replaceable):
|
11
|
+
def merged(self, *args):
|
12
|
+
"""Perform a shallow merge, where the last non-None write wins. This is
|
13
|
+
intended to merge dataclasses that are a collection of optional values.
|
14
|
+
"""
|
15
|
+
replacements = {}
|
16
|
+
cls = type(self)
|
17
|
+
for arg in args:
|
18
|
+
for field in dataclasses.fields(cls):
|
19
|
+
value = getattr(arg, field.name)
|
20
|
+
if value is not None:
|
21
|
+
replacements[field.name] = value
|
22
|
+
|
23
|
+
return self.replace(**replacements)
|
dbt_common/dataclass_schema.py
CHANGED
@@ -47,7 +47,9 @@ class dbtMashConfig(MashBaseConfig):
|
|
47
47
|
# This class pulls in DataClassDictMixin from Mashumaro. The 'to_dict'
|
48
48
|
# and 'from_dict' methods come from Mashumaro.
|
49
49
|
class dbtClassMixin(DataClassDictMixin):
|
50
|
-
"""
|
50
|
+
"""Convert and validate JSON schemas.
|
51
|
+
|
52
|
+
The Mixin adds methods to generate a JSON schema and
|
51
53
|
convert to and from JSON encodable dicts with validation
|
52
54
|
against the schema
|
53
55
|
"""
|
dbt_common/events/__init__.py
CHANGED
@@ -4,4 +4,6 @@ from dbt_common.events.functions import get_stdout_config
|
|
4
4
|
from dbt_common.events.logger import LineFormat
|
5
5
|
|
6
6
|
# make sure event manager starts with a logger
|
7
|
-
get_event_manager().add_logger(
|
7
|
+
get_event_manager().add_logger(
|
8
|
+
get_stdout_config(LineFormat.PlainText, True, EventLevel.INFO, False)
|
9
|
+
)
|
dbt_common/events/base_types.py
CHANGED
@@ -49,7 +49,7 @@ class EventLevel(str, Enum):
|
|
49
49
|
|
50
50
|
|
51
51
|
class BaseEvent:
|
52
|
-
"""BaseEvent for proto message generated python events"""
|
52
|
+
"""BaseEvent for proto message generated python events."""
|
53
53
|
|
54
54
|
PROTO_TYPES_MODULE = types_pb2
|
55
55
|
|
@@ -59,7 +59,9 @@ class BaseEvent:
|
|
59
59
|
if class_name == "Formatting" and len(args) > 0:
|
60
60
|
kwargs["msg"] = args[0]
|
61
61
|
args = ()
|
62
|
-
assert
|
62
|
+
assert (
|
63
|
+
len(args) == 0
|
64
|
+
), f"[{class_name}] Don't use positional arguments when constructing logging events"
|
63
65
|
if "base_msg" in kwargs:
|
64
66
|
kwargs["base_msg"] = str(kwargs["base_msg"])
|
65
67
|
if "msg" in kwargs:
|
@@ -92,7 +94,9 @@ class BaseEvent:
|
|
92
94
|
return super().__getattribute__("pb_msg").__getattribute__(key)
|
93
95
|
|
94
96
|
def to_dict(self):
|
95
|
-
return MessageToDict(
|
97
|
+
return MessageToDict(
|
98
|
+
self.pb_msg, preserving_proto_field_name=True, including_default_value_fields=True
|
99
|
+
)
|
96
100
|
|
97
101
|
def to_json(self) -> str:
|
98
102
|
return MessageToJson(
|
@@ -125,7 +129,6 @@ class EventMsg(Protocol):
|
|
125
129
|
|
126
130
|
|
127
131
|
def msg_from_base_event(event: BaseEvent, level: Optional[EventLevel] = None):
|
128
|
-
|
129
132
|
msg_class_name = f"{type(event).__name__}Msg"
|
130
133
|
msg_cls = getattr(event.PROTO_TYPES_MODULE, msg_class_name)
|
131
134
|
|
@@ -17,7 +17,8 @@ _log_level_to_event_level_map = {
|
|
17
17
|
|
18
18
|
|
19
19
|
class DbtEventLoggingHandler(logging.Handler):
|
20
|
-
"""A logging handler that wraps the EventManager
|
20
|
+
"""A logging handler that wraps the EventManager.
|
21
|
+
|
21
22
|
This allows non-dbt packages to log to the dbt event stream.
|
22
23
|
All logs are generated as "Note" events.
|
23
24
|
"""
|
@@ -20,7 +20,8 @@ class EventManager:
|
|
20
20
|
msg.SerializeToString()
|
21
21
|
except Exception as exc:
|
22
22
|
raise Exception(
|
23
|
-
f"{msg.info.name} is not serializable to binary.
|
23
|
+
f"{msg.info.name} is not serializable to binary. ",
|
24
|
+
f"Originating exception: {exc}, {traceback.format_exc()}",
|
24
25
|
)
|
25
26
|
|
26
27
|
for logger in self.loggers:
|
@@ -31,7 +32,9 @@ class EventManager:
|
|
31
32
|
callback(msg)
|
32
33
|
|
33
34
|
def add_logger(self, config: LoggerConfig) -> None:
|
34
|
-
logger =
|
35
|
+
logger = (
|
36
|
+
_JsonLogger(config) if config.line_format == LineFormat.Json else _TextLogger(config)
|
37
|
+
)
|
35
38
|
self.loggers.append(logger)
|
36
39
|
|
37
40
|
def flush(self) -> None:
|
dbt_common/events/format.py
CHANGED
@@ -30,7 +30,9 @@ def format_fancy_output_line(
|
|
30
30
|
else:
|
31
31
|
status_time = " in {execution_time:0.2f}s".format(execution_time=execution_time)
|
32
32
|
|
33
|
-
output = "{justified} [{status}{status_time}]".format(
|
33
|
+
output = "{justified} [{status}{status_time}]".format(
|
34
|
+
justified=justified, status=status, status_time=status_time
|
35
|
+
)
|
34
36
|
|
35
37
|
return output
|
36
38
|
|
dbt_common/events/functions.py
CHANGED
@@ -3,7 +3,7 @@ from pathlib import Path
|
|
3
3
|
from dbt_common.events.event_manager_client import get_event_manager
|
4
4
|
from dbt_common.invocation import get_invocation_id
|
5
5
|
from dbt_common.helper_types import WarnErrorOptions
|
6
|
-
from dbt_common.utils import ForgivingJSONEncoder
|
6
|
+
from dbt_common.utils.encoding import ForgivingJSONEncoder
|
7
7
|
from dbt_common.events.base_types import BaseEvent, EventLevel, EventMsg
|
8
8
|
from dbt_common.events.logger import LoggerConfig, LineFormat
|
9
9
|
from dbt_common.exceptions import scrub_secrets, env_secrets
|
@@ -94,20 +94,27 @@ def msg_to_dict(msg: EventMsg) -> dict:
|
|
94
94
|
msg_dict = dict()
|
95
95
|
try:
|
96
96
|
msg_dict = MessageToDict(
|
97
|
-
msg,
|
97
|
+
msg,
|
98
|
+
preserving_proto_field_name=True,
|
99
|
+
including_default_value_fields=True, # type: ignore
|
98
100
|
)
|
99
101
|
except Exception as exc:
|
100
102
|
event_type = type(msg).__name__
|
101
|
-
fire_event(
|
103
|
+
fire_event(
|
104
|
+
Note(msg=f"type {event_type} is not serializable. {str(exc)}"), level=EventLevel.WARN
|
105
|
+
)
|
102
106
|
# We don't want an empty NodeInfo in output
|
103
|
-
if
|
107
|
+
if (
|
108
|
+
"data" in msg_dict
|
109
|
+
and "node_info" in msg_dict["data"]
|
110
|
+
and msg_dict["data"]["node_info"]["node_name"] == ""
|
111
|
+
):
|
104
112
|
del msg_dict["data"]["node_info"]
|
105
113
|
return msg_dict
|
106
114
|
|
107
115
|
|
108
116
|
def warn_or_error(event, node=None) -> None:
|
109
117
|
if WARN_ERROR or WARN_ERROR_OPTIONS.includes(type(event).__name__):
|
110
|
-
|
111
118
|
# TODO: resolve this circular import when at top
|
112
119
|
from dbt_common.exceptions import EventCompilationError
|
113
120
|
|
@@ -118,16 +125,13 @@ def warn_or_error(event, node=None) -> None:
|
|
118
125
|
|
119
126
|
# an alternative to fire_event which only creates and logs the event value
|
120
127
|
# if the condition is met. Does nothing otherwise.
|
121
|
-
def fire_event_if(
|
128
|
+
def fire_event_if(
|
129
|
+
conditional: bool, lazy_e: Callable[[], BaseEvent], level: Optional[EventLevel] = None
|
130
|
+
) -> None:
|
122
131
|
if conditional:
|
123
132
|
fire_event(lazy_e(), level=level)
|
124
133
|
|
125
134
|
|
126
|
-
# a special case of fire_event_if, to only fire events in our unit/functional tests
|
127
|
-
def fire_event_if_test(lazy_e: Callable[[], BaseEvent], level: Optional[EventLevel] = None) -> None:
|
128
|
-
fire_event_if(conditional=("pytest" in sys.modules), lazy_e=lazy_e, level=level)
|
129
|
-
|
130
|
-
|
131
135
|
# top-level method for accessing the new eventing system
|
132
136
|
# this is where all the side effects happen branched by event type
|
133
137
|
# (i.e. - mutating the event history, printing to stdout, logging
|
@@ -140,7 +144,9 @@ def get_metadata_vars() -> Dict[str, str]:
|
|
140
144
|
global metadata_vars
|
141
145
|
if metadata_vars is None:
|
142
146
|
metadata_vars = {
|
143
|
-
k[len(_METADATA_ENV_PREFIX) :]: v
|
147
|
+
k[len(_METADATA_ENV_PREFIX) :]: v
|
148
|
+
for k, v in os.environ.items()
|
149
|
+
if k.startswith(_METADATA_ENV_PREFIX)
|
144
150
|
}
|
145
151
|
return metadata_vars
|
146
152
|
|
dbt_common/events/logger.py
CHANGED
@@ -11,7 +11,7 @@ from colorama import Style
|
|
11
11
|
|
12
12
|
from dbt_common.events.base_types import EventLevel, EventMsg
|
13
13
|
from dbt_common.events.format import timestamp_to_datetime_string
|
14
|
-
from dbt_common.utils import ForgivingJSONEncoder
|
14
|
+
from dbt_common.utils.encoding import ForgivingJSONEncoder
|
15
15
|
|
16
16
|
# A Filter is a function which takes a BaseEvent and returns True if the event
|
17
17
|
# should be logged, False otherwise.
|
@@ -51,19 +51,21 @@ _log_level_map = {
|
|
51
51
|
# We need this function for now because the numeric log severity levels in
|
52
52
|
# Python do not match those for logbook, so we have to explicitly call the
|
53
53
|
# correct function by name.
|
54
|
-
def send_to_logger(
|
54
|
+
def send_to_logger(logger, level: str, log_line: str):
|
55
55
|
if level == "test":
|
56
|
-
|
56
|
+
logger.debug(log_line)
|
57
57
|
elif level == "debug":
|
58
|
-
|
58
|
+
logger.debug(log_line)
|
59
59
|
elif level == "info":
|
60
|
-
|
60
|
+
logger.info(log_line)
|
61
61
|
elif level == "warn":
|
62
|
-
|
62
|
+
logger.warning(log_line)
|
63
63
|
elif level == "error":
|
64
|
-
|
64
|
+
logger.error(log_line)
|
65
65
|
else:
|
66
|
-
raise AssertionError(
|
66
|
+
raise AssertionError(
|
67
|
+
f"While attempting to log {log_line}, encountered the unhandled level: {level}"
|
68
|
+
)
|
67
69
|
|
68
70
|
|
69
71
|
@dataclass
|
@@ -150,7 +152,9 @@ class _TextLogger(_Logger):
|
|
150
152
|
log_line = f"\n\n{separator} {ts} | {self.invocation_id} {separator}\n"
|
151
153
|
scrubbed_msg: str = self.scrubber(msg.info.msg) # type: ignore
|
152
154
|
level = msg.info.level
|
153
|
-
log_line +=
|
155
|
+
log_line += (
|
156
|
+
f"{self._get_color_tag()}{ts} [{level:<5}]{self._get_thread_name()} {scrubbed_msg}"
|
157
|
+
)
|
154
158
|
return log_line
|
155
159
|
|
156
160
|
def _get_color_tag(self) -> str:
|
dbt_common/events/types.py
CHANGED
@@ -113,9 +113,12 @@ class Formatting(InfoLevel):
|
|
113
113
|
|
114
114
|
|
115
115
|
class Note(InfoLevel):
|
116
|
-
"""
|
116
|
+
"""Unstructured events.
|
117
|
+
|
118
|
+
The Note event provides a way to log messages which aren't likely to be
|
117
119
|
useful as more structured events. For console formatting text like empty
|
118
|
-
lines and separator bars, use the Formatting event instead.
|
120
|
+
lines and separator bars, use the Formatting event instead.
|
121
|
+
"""
|
119
122
|
|
120
123
|
def code(self) -> str:
|
121
124
|
return "Z050"
|
dbt_common/events/types_pb2.py
CHANGED
@@ -2,11 +2,10 @@
|
|
2
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
3
|
# source: types.proto
|
4
4
|
"""Generated protocol buffer code."""
|
5
|
+
from google.protobuf.internal import builder as _builder
|
5
6
|
from google.protobuf import descriptor as _descriptor
|
6
7
|
from google.protobuf import descriptor_pool as _descriptor_pool
|
7
8
|
from google.protobuf import symbol_database as _symbol_database
|
8
|
-
from google.protobuf.internal import builder as _builder
|
9
|
-
|
10
9
|
# @@protoc_insertion_point(imports)
|
11
10
|
|
12
11
|
_sym_db = _symbol_database.Default()
|
@@ -15,58 +14,55 @@ _sym_db = _symbol_database.Default()
|
|
15
14
|
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
|
16
15
|
|
17
16
|
|
18
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
|
19
|
-
b'\n\x0btypes.proto\x12\x0bproto_types\x1a\x1fgoogle/protobuf/timestamp.proto"\x91\x02\n\tEventInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\x12\x0b\n\x03msg\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\t\x12\x15\n\rinvocation_id\x18\x05 \x01(\t\x12\x0b\n\x03pid\x18\x06 \x01(\x05\x12\x0e\n\x06thread\x18\x07 \x01(\t\x12&\n\x02ts\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x05\x65xtra\x18\t \x03(\x0b\x32!.proto_types.EventInfo.ExtraEntry\x12\x10\n\x08\x63\x61tegory\x18\n \x01(\t\x1a,\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"6\n\x0eGenericMessage\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo"1\n\x11RetryExternalCall\x12\x0f\n\x07\x61ttempt\x18\x01 \x01(\x05\x12\x0b\n\x03max\x18\x02 \x01(\x05"j\n\x14RetryExternalCallMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12,\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1e.proto_types.RetryExternalCall"#\n\x14RecordRetryException\x12\x0b\n\x03\x65xc\x18\x01 \x01(\t"p\n\x17RecordRetryExceptionMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12/\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32!.proto_types.RecordRetryException"@\n\x13SystemCouldNotWrite\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\x0b\n\x03\x65xc\x18\x03 \x01(\t"n\n\x16SystemCouldNotWriteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12.\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .proto_types.SystemCouldNotWrite"!\n\x12SystemExecutingCmd\x12\x0b\n\x03\x63md\x18\x01 \x03(\t"l\n\x15SystemExecutingCmdMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12-\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1f.proto_types.SystemExecutingCmd"\x1c\n\x0cSystemStdOut\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t"`\n\x0fSystemStdOutMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdOut"\x1c\n\x0cSystemStdErr\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t"`\n\x0fSystemStdErrMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdErr",\n\x16SystemReportReturnCode\x12\x12\n\nreturncode\x18\x01 \x01(\x05"t\n\x19SystemReportReturnCodeMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x31\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32#.proto_types.SystemReportReturnCode"\x19\n\nFormatting\x12\x0b\n\x03msg\x18\x01 \x01(\t"\\\n\rFormattingMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12%\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x17.proto_types.Formatting"\x13\n\x04Note\x12\x0b\n\x03msg\x18\x01 \x01(\t"P\n\x07NoteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x1f\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x11.proto_types.Noteb\x06proto3'
|
20
|
-
)
|
17
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x0bproto_types\x1a\x1fgoogle/protobuf/timestamp.proto\"\x91\x02\n\tEventInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\x12\x0b\n\x03msg\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\t\x12\x15\n\rinvocation_id\x18\x05 \x01(\t\x12\x0b\n\x03pid\x18\x06 \x01(\x05\x12\x0e\n\x06thread\x18\x07 \x01(\t\x12&\n\x02ts\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x05\x65xtra\x18\t \x03(\x0b\x32!.proto_types.EventInfo.ExtraEntry\x12\x10\n\x08\x63\x61tegory\x18\n \x01(\t\x1a,\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"6\n\x0eGenericMessage\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\"1\n\x11RetryExternalCall\x12\x0f\n\x07\x61ttempt\x18\x01 \x01(\x05\x12\x0b\n\x03max\x18\x02 \x01(\x05\"j\n\x14RetryExternalCallMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12,\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1e.proto_types.RetryExternalCall\"#\n\x14RecordRetryException\x12\x0b\n\x03\x65xc\x18\x01 \x01(\t\"p\n\x17RecordRetryExceptionMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12/\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32!.proto_types.RecordRetryException\"@\n\x13SystemCouldNotWrite\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\x0b\n\x03\x65xc\x18\x03 \x01(\t\"n\n\x16SystemCouldNotWriteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12.\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .proto_types.SystemCouldNotWrite\"!\n\x12SystemExecutingCmd\x12\x0b\n\x03\x63md\x18\x01 \x03(\t\"l\n\x15SystemExecutingCmdMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12-\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1f.proto_types.SystemExecutingCmd\"\x1c\n\x0cSystemStdOut\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t\"`\n\x0fSystemStdOutMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdOut\"\x1c\n\x0cSystemStdErr\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t\"`\n\x0fSystemStdErrMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdErr\",\n\x16SystemReportReturnCode\x12\x12\n\nreturncode\x18\x01 \x01(\x05\"t\n\x19SystemReportReturnCodeMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x31\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32#.proto_types.SystemReportReturnCode\"\x19\n\nFormatting\x12\x0b\n\x03msg\x18\x01 \x01(\t\"\\\n\rFormattingMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12%\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x17.proto_types.Formatting\"\x13\n\x04Note\x12\x0b\n\x03msg\x18\x01 \x01(\t\"P\n\x07NoteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x1f\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x11.proto_types.Noteb\x06proto3')
|
21
18
|
|
22
|
-
|
23
|
-
_builder.
|
24
|
-
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "types_pb2", _globals)
|
19
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
20
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'types_pb2', globals())
|
25
21
|
if _descriptor._USE_C_DESCRIPTORS == False:
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
23
|
+
DESCRIPTOR._options = None
|
24
|
+
_EVENTINFO_EXTRAENTRY._options = None
|
25
|
+
_EVENTINFO_EXTRAENTRY._serialized_options = b'8\001'
|
26
|
+
_EVENTINFO._serialized_start=62
|
27
|
+
_EVENTINFO._serialized_end=335
|
28
|
+
_EVENTINFO_EXTRAENTRY._serialized_start=291
|
29
|
+
_EVENTINFO_EXTRAENTRY._serialized_end=335
|
30
|
+
_GENERICMESSAGE._serialized_start=337
|
31
|
+
_GENERICMESSAGE._serialized_end=391
|
32
|
+
_RETRYEXTERNALCALL._serialized_start=393
|
33
|
+
_RETRYEXTERNALCALL._serialized_end=442
|
34
|
+
_RETRYEXTERNALCALLMSG._serialized_start=444
|
35
|
+
_RETRYEXTERNALCALLMSG._serialized_end=550
|
36
|
+
_RECORDRETRYEXCEPTION._serialized_start=552
|
37
|
+
_RECORDRETRYEXCEPTION._serialized_end=587
|
38
|
+
_RECORDRETRYEXCEPTIONMSG._serialized_start=589
|
39
|
+
_RECORDRETRYEXCEPTIONMSG._serialized_end=701
|
40
|
+
_SYSTEMCOULDNOTWRITE._serialized_start=703
|
41
|
+
_SYSTEMCOULDNOTWRITE._serialized_end=767
|
42
|
+
_SYSTEMCOULDNOTWRITEMSG._serialized_start=769
|
43
|
+
_SYSTEMCOULDNOTWRITEMSG._serialized_end=879
|
44
|
+
_SYSTEMEXECUTINGCMD._serialized_start=881
|
45
|
+
_SYSTEMEXECUTINGCMD._serialized_end=914
|
46
|
+
_SYSTEMEXECUTINGCMDMSG._serialized_start=916
|
47
|
+
_SYSTEMEXECUTINGCMDMSG._serialized_end=1024
|
48
|
+
_SYSTEMSTDOUT._serialized_start=1026
|
49
|
+
_SYSTEMSTDOUT._serialized_end=1054
|
50
|
+
_SYSTEMSTDOUTMSG._serialized_start=1056
|
51
|
+
_SYSTEMSTDOUTMSG._serialized_end=1152
|
52
|
+
_SYSTEMSTDERR._serialized_start=1154
|
53
|
+
_SYSTEMSTDERR._serialized_end=1182
|
54
|
+
_SYSTEMSTDERRMSG._serialized_start=1184
|
55
|
+
_SYSTEMSTDERRMSG._serialized_end=1280
|
56
|
+
_SYSTEMREPORTRETURNCODE._serialized_start=1282
|
57
|
+
_SYSTEMREPORTRETURNCODE._serialized_end=1326
|
58
|
+
_SYSTEMREPORTRETURNCODEMSG._serialized_start=1328
|
59
|
+
_SYSTEMREPORTRETURNCODEMSG._serialized_end=1444
|
60
|
+
_FORMATTING._serialized_start=1446
|
61
|
+
_FORMATTING._serialized_end=1471
|
62
|
+
_FORMATTINGMSG._serialized_start=1473
|
63
|
+
_FORMATTINGMSG._serialized_end=1565
|
64
|
+
_NOTE._serialized_start=1567
|
65
|
+
_NOTE._serialized_end=1586
|
66
|
+
_NOTEMSG._serialized_start=1588
|
67
|
+
_NOTEMSG._serialized_end=1668
|
72
68
|
# @@protoc_insertion_point(module_scope)
|
dbt_common/exceptions/base.py
CHANGED
@@ -92,9 +92,7 @@ class DbtRuntimeError(RuntimeError, DbtBaseException):
|
|
92
92
|
return "Runtime"
|
93
93
|
|
94
94
|
def node_to_string(self, node: Any):
|
95
|
-
"""
|
96
|
-
Given a node-like object we attempt to create the best identifier we can
|
97
|
-
"""
|
95
|
+
"""Given a node-like object we attempt to create the best identifier we can."""
|
98
96
|
result = ""
|
99
97
|
if hasattr(node, "resource_type"):
|
100
98
|
result += node.resource_type
|
@@ -125,8 +123,9 @@ class DbtRuntimeError(RuntimeError, DbtBaseException):
|
|
125
123
|
return lines
|
126
124
|
|
127
125
|
def validator_error_message(self, exc: builtins.Exception):
|
128
|
-
"""Given a dbt.dataclass_schema.ValidationError
|
129
|
-
|
126
|
+
"""Given a dbt.dataclass_schema.ValidationError return the relevant parts as a string.
|
127
|
+
|
128
|
+
dbt.dataclass_schema.ValidationError is basically a jsonschema.ValidationError)
|
130
129
|
"""
|
131
130
|
if not isinstance(exc, ValidationError):
|
132
131
|
return str(exc)
|
@@ -175,9 +174,14 @@ class CompilationError(DbtRuntimeError):
|
|
175
174
|
|
176
175
|
def _fix_dupe_msg(self, path_1: str, path_2: str, name: str, type_name: str) -> str:
|
177
176
|
if path_1 == path_2:
|
178
|
-
return
|
177
|
+
return (
|
178
|
+
f"remove one of the {type_name} entries for {name} in this file:\n - {path_1!s}\n"
|
179
|
+
)
|
179
180
|
else:
|
180
|
-
return
|
181
|
+
return (
|
182
|
+
f"remove the {type_name} entry for {name} in one of these files:\n"
|
183
|
+
f" - {path_1!s}\n{path_2!s}"
|
184
|
+
)
|
181
185
|
|
182
186
|
|
183
187
|
class RecursionError(DbtRuntimeError):
|
dbt_common/exceptions/cache.py
CHANGED
@@ -15,7 +15,9 @@ class NewNameAlreadyInCacheError(CacheInconsistencyError):
|
|
15
15
|
def __init__(self, old_key: str, new_key: str):
|
16
16
|
self.old_key = old_key
|
17
17
|
self.new_key = new_key
|
18
|
-
msg =
|
18
|
+
msg = (
|
19
|
+
f'in rename of "{self.old_key}" -> "{self.new_key}", new name is in the cache already'
|
20
|
+
)
|
19
21
|
super().__init__(msg)
|
20
22
|
|
21
23
|
|
@@ -55,7 +57,10 @@ class TruncatedModelNameCausedCollisionError(CacheInconsistencyError):
|
|
55
57
|
else:
|
56
58
|
message_addendum = ""
|
57
59
|
|
58
|
-
msg =
|
60
|
+
msg = (
|
61
|
+
f"in rename, new key {self.new_key} already in "
|
62
|
+
f"cache: {list(self.relations.keys())}{message_addendum}"
|
63
|
+
)
|
59
64
|
|
60
65
|
return msg
|
61
66
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class ConnectionError(Exception):
|
2
|
-
"""
|
3
|
-
|
4
|
-
|
2
|
+
"""ConnectionError.
|
3
|
+
|
4
|
+
Connection that returned a bad response, timed out, or resulted
|
5
|
+
in a file that is corrupt.
|
5
6
|
"""
|
6
7
|
|
7
8
|
pass
|
dbt_common/exceptions/jinja.py
CHANGED
@@ -24,7 +24,8 @@ class MissingCloseTagError(CompilationError):
|
|
24
24
|
|
25
25
|
def get_message(self) -> str:
|
26
26
|
msg = (
|
27
|
-
|
27
|
+
"Reached EOF without finding a close tag for "
|
28
|
+
f"{self.block_type_name} (searched from line {self.linecount})"
|
28
29
|
)
|
29
30
|
return msg
|
30
31
|
|
dbt_common/exceptions/macros.py
CHANGED
@@ -4,10 +4,9 @@ from dbt_common.exceptions import CompilationError, DbtBaseException
|
|
4
4
|
|
5
5
|
|
6
6
|
class MacroReturn(DbtBaseException):
|
7
|
-
"""
|
7
|
+
"""This is how we return a value from a macro, not an exception.
|
8
|
+
|
8
9
|
Hack of all hacks
|
9
|
-
This is not actually an exception.
|
10
|
-
It's how we return a value from a macro.
|
11
10
|
"""
|
12
11
|
|
13
12
|
def __init__(self, value) -> None:
|
@@ -66,7 +65,10 @@ class MacroNameNotStringError(CompilationError):
|
|
66
65
|
super().__init__(msg=self.get_message())
|
67
66
|
|
68
67
|
def get_message(self) -> str:
|
69
|
-
msg =
|
68
|
+
msg = (
|
69
|
+
f"The macro_name parameter ({self.kwarg_value}) "
|
70
|
+
"to adapter.dispatch was not a string"
|
71
|
+
)
|
70
72
|
return msg
|
71
73
|
|
72
74
|
|
@@ -102,6 +104,9 @@ class MacroResultError(CompilationError):
|
|
102
104
|
super().__init__(msg=self.get_message())
|
103
105
|
|
104
106
|
def get_message(self) -> str:
|
105
|
-
msg =
|
107
|
+
msg = (
|
108
|
+
f'Got an invalid result from "{self.freshness_macro_name}" '
|
109
|
+
f"macro: {[tuple(r) for r in self.table]}"
|
110
|
+
)
|
106
111
|
|
107
112
|
return msg
|
dbt_common/helper_types.py
CHANGED
@@ -25,7 +25,7 @@ class NVEnum(StrEnum):
|
|
25
25
|
|
26
26
|
@dataclass
|
27
27
|
class NoValue(dbtClassMixin):
|
28
|
-
"""Sometimes, you want a way to say none that isn't None"""
|
28
|
+
"""Sometimes, you want a way to say none that isn't None!"""
|
29
29
|
|
30
30
|
novalue: NVEnum = field(default_factory=lambda: NVEnum.novalue)
|
31
31
|
|
@@ -39,10 +39,14 @@ class IncludeExclude(dbtClassMixin):
|
|
39
39
|
|
40
40
|
def __post_init__(self):
|
41
41
|
if isinstance(self.include, str) and self.include not in self.INCLUDE_ALL:
|
42
|
-
raise ValidationError(
|
42
|
+
raise ValidationError(
|
43
|
+
f"include must be one of {self.INCLUDE_ALL} or a list of strings"
|
44
|
+
)
|
43
45
|
|
44
46
|
if self.exclude and self.include not in self.INCLUDE_ALL:
|
45
|
-
raise ValidationError(
|
47
|
+
raise ValidationError(
|
48
|
+
f"exclude can only be specified if include is one of {self.INCLUDE_ALL}"
|
49
|
+
)
|
46
50
|
|
47
51
|
if isinstance(self.include, list):
|
48
52
|
self._validate_items(self.include)
|
@@ -51,7 +55,9 @@ class IncludeExclude(dbtClassMixin):
|
|
51
55
|
self._validate_items(self.exclude)
|
52
56
|
|
53
57
|
def includes(self, item_name: str):
|
54
|
-
return (
|
58
|
+
return (
|
59
|
+
item_name in self.include or self.include in self.INCLUDE_ALL
|
60
|
+
) and item_name not in self.exclude
|
55
61
|
|
56
62
|
def _validate_items(self, items: List[str]):
|
57
63
|
pass
|