-
Notifications
You must be signed in to change notification settings - Fork 374
Expand file tree
/
Copy pathsource.py
More file actions
118 lines (100 loc) · 4.4 KB
/
source.py
File metadata and controls
118 lines (100 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from __future__ import annotations
import typing as t
from pydantic import Field
from sqlmesh.core.config.base import UpdateStrategy
from sqlmesh.dbt.column import ColumnConfig
from sqlmesh.dbt.common import GeneralConfig
from sqlmesh.dbt.relation import RelationType
from sqlmesh.dbt.util import DBT_VERSION
from sqlmesh.utils import AttributeDict
from sqlmesh.utils.errors import ConfigError
if t.TYPE_CHECKING:
from sqlmesh.dbt.context import DbtContext
class SourceConfig(GeneralConfig):
"""
Args:
name: The name of the table
source_name: The name of the source that defines the table
database: Name of the database where the table is stored. By default, the project's target database is used.
schema: The scehma name as stored in the database. If not specified, the source name is used.
identifier: The table name as stored in the database. If not specified, the source table name is used
loader: Describes the tool that loads the source into the warehouse
overrides: Override a source defined in the specified package
freshness: Dictionary specifying maximum time, since the most recent record, to consider the source fresh
loaded_at_field: Column name or expression that returns a timestamp indicating freshness
quoting: Define which components of the qualified name (database, schema, identifier) to quote when resolving the source() method
external: Dictionary of metadata properties specific to sources that point to external tables
columns: Columns within the source
"""
# DBT configuration fields
name: str = ""
source_name_: str = Field("", alias="source_name")
fqn_: t.List[str] = Field(default_factory=list, alias="fqn")
database: t.Optional[str] = None
schema_: t.Optional[str] = Field(None, alias="schema")
identifier: t.Optional[str] = None
loader: t.Optional[str] = None
overrides: t.Optional[str] = None
freshness: t.Optional[t.Dict[str, t.Any]] = {}
loaded_at_field: t.Optional[str] = None
quoting: t.Dict[str, t.Optional[bool]] = {}
external: t.Optional[t.Dict[str, t.Any]] = {}
source_meta: t.Optional[t.Dict[str, t.Any]] = {}
columns: t.Dict[str, ColumnConfig] = {}
event_time: t.Optional[str] = None
_canonical_name: t.Optional[str] = None
_FIELD_UPDATE_STRATEGY: t.ClassVar[t.Dict[str, UpdateStrategy]] = {
**GeneralConfig._FIELD_UPDATE_STRATEGY,
**{"columns": UpdateStrategy.KEY_EXTEND},
}
@property
def table_name(self) -> t.Optional[str]:
return self.identifier or self.name
@property
def config_name(self) -> str:
return f"{self.source_name_}.{self.name}"
@property
def fqn(self) -> str:
return ".".join(self.fqn_)
def canonical_name(self, context: DbtContext) -> str:
if self._canonical_name is None:
source = context.get_callable_macro("source")
if not source:
raise ConfigError("'source' macro not found.")
try:
relation = source(self.source_name_, self.name)
except Exception as e:
raise ConfigError(
f"'source' macro failed for '{self.config_name}' with exeception '{e}'."
)
relation = relation.quote(
database=False,
schema=False,
identifier=False,
)
if relation.database == context.target.database:
relation = relation.include(database=False)
self._canonical_name = relation.render()
return self._canonical_name
@property
def relation_info(self) -> AttributeDict:
extras = {}
external_location = (
self.source_meta.get("external_location", None) if self.source_meta else None
)
if external_location:
extras["external"] = external_location.replace("{name}", self.table_name)
if DBT_VERSION >= (1, 9, 0) and self.event_time:
extras["event_time_filter"] = {
"field_name": self.event_time,
}
return AttributeDict(
{
"database": self.database,
"schema": self.schema_,
"identifier": self.table_name,
"type": RelationType.External.value,
"quote_policy": AttributeDict(self.quoting),
**extras,
}
)