-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathrelation.py
110 lines (95 loc) · 3.88 KB
/
relation.py
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
from dataclasses import dataclass, field
from dbt.adapters.contracts.relation import RelationConfig
from typing import FrozenSet, Optional
from dbt.adapters.base.relation import BaseRelation
from dbt.adapters.relation_configs import (
RelationConfigBase,
RelationConfigChangeAction,
RelationResults,
)
from dbt.adapters.base import RelationType
from dbt_common.exceptions import DbtRuntimeError
from dbt.adapters.redshift.relation_configs import (
RedshiftMaterializedViewConfig,
RedshiftMaterializedViewConfigChangeset,
RedshiftAutoRefreshConfigChange,
RedshiftDistConfigChange,
RedshiftSortConfigChange,
RedshiftIncludePolicy,
RedshiftQuotePolicy,
MAX_CHARACTERS_IN_IDENTIFIER,
)
@dataclass(frozen=True, eq=False, repr=False)
class RedshiftRelation(BaseRelation):
include_policy = RedshiftIncludePolicy # type: ignore
quote_policy = RedshiftQuotePolicy # type: ignore
require_alias: bool = False
relation_configs = {
RelationType.MaterializedView.value: RedshiftMaterializedViewConfig,
}
renameable_relations: FrozenSet[RelationType] = field(
default_factory=lambda: frozenset(
{
RelationType.View,
RelationType.Table,
}
)
)
replaceable_relations: FrozenSet[RelationType] = field(
default_factory=lambda: frozenset(
{
RelationType.View,
}
)
)
def __post_init__(self):
# Check for length of Redshift table/view names.
# Check self.type to exclude test relation identifiers
if (
self.identifier is not None
and self.type is not None
and len(self.identifier) > MAX_CHARACTERS_IN_IDENTIFIER
):
raise DbtRuntimeError(
f"Relation name '{self.identifier}' "
f"is longer than {MAX_CHARACTERS_IN_IDENTIFIER} characters"
)
def relation_max_name_length(self):
return MAX_CHARACTERS_IN_IDENTIFIER
@classmethod
def from_config(cls, config: RelationConfig) -> RelationConfigBase:
relation_type: str = config.config.materialized # type: ignore
if relation_config := cls.relation_configs.get(relation_type):
return relation_config.from_relation_config(config)
raise DbtRuntimeError(
f"from_config() is not supported for the provided relation type: {relation_type}"
)
@classmethod
def materialized_view_config_changeset(
cls, relation_results: RelationResults, relation_config: RelationConfig
) -> Optional[RedshiftMaterializedViewConfigChangeset]:
config_change_collection = RedshiftMaterializedViewConfigChangeset()
existing_materialized_view = RedshiftMaterializedViewConfig.from_relation_results(
relation_results
)
new_materialized_view = RedshiftMaterializedViewConfig.from_relation_config(
relation_config
)
if new_materialized_view.autorefresh != existing_materialized_view.autorefresh:
config_change_collection.autorefresh = RedshiftAutoRefreshConfigChange(
action=RelationConfigChangeAction.alter,
context=new_materialized_view.autorefresh,
)
if new_materialized_view.dist != existing_materialized_view.dist:
config_change_collection.dist = RedshiftDistConfigChange(
action=RelationConfigChangeAction.alter,
context=new_materialized_view.dist,
)
if new_materialized_view.sort != existing_materialized_view.sort:
config_change_collection.sort = RedshiftSortConfigChange(
action=RelationConfigChangeAction.alter,
context=new_materialized_view.sort,
)
if config_change_collection.has_changes:
return config_change_collection
return None