Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[state:modified] store unrendered_database and unrendered_schema on source definition for state:modified comparisons #10675

Merged
merged 42 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
1659c7b
persist schema yml unrendered_config before rendering
MichelleArk Jul 26, 2024
8ad3c03
persist unrendered config on schema file instead of manifest
MichelleArk Jul 26, 2024
4f96f5c
update test_configs_in_schema_files.py
MichelleArk Jul 26, 2024
acd23b0
support versioning in SchemaSourceFile.add_unrendered_config
MichelleArk Jul 26, 2024
9e10428
Merge branch 'main' into state-modified-source-tests
MichelleArk Aug 12, 2024
fe9b572
fix: do not use None for version key in unrendered_configs
MichelleArk Aug 12, 2024
f368cdf
support reliable unrendered_config in .sql files
MichelleArk Aug 12, 2024
57db0bf
more reliably set unrendered_config_call_dict + prefer config_call_di…
MichelleArk Aug 19, 2024
1ce11ec
store + reset unrendered_config_call_dict on node
MichelleArk Aug 20, 2024
bad5723
Merge branch 'main' into state-modified-source-tests
MichelleArk Aug 22, 2024
ce2b150
Merge branch 'main' into state-modified-source-tests
MichelleArk Sep 4, 2024
bad6b92
first pass: put behind legacy flag
MichelleArk Sep 4, 2024
d8bf0e6
fix SnapshotParserTest unit test
MichelleArk Sep 5, 2024
fad1295
Return early to avoid creating jinja environemt if no config call in …
MichelleArk Sep 6, 2024
47b18b1
test var sensitivity with require_config_jinja_insensitivity_for_stat…
MichelleArk Sep 6, 2024
d625a23
cleanup comment
MichelleArk Sep 6, 2024
7d979be
store unrendered database on source definition
MichelleArk Sep 6, 2024
33e2359
Merge branch 'main' into state-modified-source-tests
MichelleArk Sep 10, 2024
4081627
rename behaviour flag
MichelleArk Sep 10, 2024
897c2e5
Merge branch 'main' into state-modified-source-tests
MichelleArk Sep 25, 2024
ac42ec4
changelog entry
MichelleArk Sep 25, 2024
71bda2a
fix state:modified for jinja if statements in configs
MichelleArk Sep 25, 2024
8677a9a
simplify constructing unrendered_config from jinja
MichelleArk Sep 25, 2024
9adb4b8
update unit tests for unrendered_config_call_dict values
MichelleArk Sep 25, 2024
8250705
Merge branch 'state-modified-source-tests' into state-modified-source…
MichelleArk Sep 25, 2024
428df36
clean up debugging print
MichelleArk Sep 25, 2024
40f1a67
put static parsing behind behaviour change flag
MichelleArk Sep 25, 2024
7986726
tests reflect behaviour flag setting
MichelleArk Sep 26, 2024
f4a5c0b
use resource_types_to_schema_file_keys to get patch unrendered configs
MichelleArk Sep 26, 2024
259d6f8
handle versioned unrendered_configs during partial parsing
MichelleArk Sep 26, 2024
1247c24
Merge branch 'state-modified-source-tests' into state-modified-source…
MichelleArk Sep 26, 2024
6f53845
fix unit tests
MichelleArk Sep 26, 2024
42d4bba
add unrendered_schema to source definition
MichelleArk Sep 26, 2024
996c46d
changelog entry
MichelleArk Sep 26, 2024
3aede61
refactor unrendered_schema and unrendered_database methods on schema …
MichelleArk Sep 26, 2024
e924bdc
Merge branch 'main' into state-modified-source-unrendered-database
MichelleArk Sep 26, 2024
1213867
refactor sources tests + pass unrendered properties to SourceDefinition
MichelleArk Sep 26, 2024
7a4892f
fix functional tests
MichelleArk Sep 30, 2024
be86bef
linting
MichelleArk Sep 30, 2024
c18e9ff
one more test
MichelleArk Sep 30, 2024
70327e7
Merge branch 'main' into state-modified-source-unrendered-database
MichelleArk Sep 30, 2024
1261b29
Merge branch 'main' into state-modified-source-unrendered-database
MichelleArk Sep 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changes/unreleased/Features-20240926-140206.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Features
body: Use unrendered database and schema source properties during state:modified,
behind state_modified_compare_more_unrendered_values behavoiur flag
time: 2024-09-26T14:02:06.732068+01:00
custom:
Author: michelleark
Issue: "9573"
2 changes: 2 additions & 0 deletions core/dbt/artifacts/resources/v1/source_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,5 @@ class SourceDefinition(ParsedSourceMandatory):
vars: Dict[str, Any] = field(default_factory=dict)
relation_name: Optional[str] = None
created_at: float = field(default_factory=lambda: time.time())
unrendered_database: Optional[str] = None
unrendered_schema: Optional[str] = None
26 changes: 26 additions & 0 deletions core/dbt/contracts/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ class SchemaSourceFile(BaseSourceFile):
sop: List[SourceKey] = field(default_factory=list)
env_vars: Dict[str, Any] = field(default_factory=dict)
unrendered_configs: Dict[str, Any] = field(default_factory=dict)
unrendered_databases: Dict[str, Any] = field(default_factory=dict)
unrendered_schemas: Dict[str, Any] = field(default_factory=dict)
vars: Dict[str, Any] = field(default_factory=dict)
pp_dict: Optional[Dict[str, Any]] = None
pp_test_index: Optional[Dict[str, Any]] = None
Expand Down Expand Up @@ -386,6 +388,30 @@ def delete_from_env_vars(self, yaml_key, name):
if not self.env_vars[yaml_key]:
del self.env_vars[yaml_key]

def add_unrendered_database(self, yaml_key: str, name: str, unrendered_database: str) -> None:
if yaml_key not in self.unrendered_databases:
self.unrendered_databases[yaml_key] = {}

self.unrendered_databases[yaml_key][name] = unrendered_database

def get_unrendered_database(self, yaml_key: str, name: str) -> Optional[str]:
if yaml_key not in self.unrendered_databases:
return None

return self.unrendered_databases[yaml_key].get(name)

def add_unrendered_schema(self, yaml_key: str, name: str, unrendered_schema: str) -> None:
if yaml_key not in self.unrendered_schemas:
self.unrendered_schemas[yaml_key] = {}

self.unrendered_schemas[yaml_key][name] = unrendered_schema

def get_unrendered_schema(self, yaml_key: str, name: str) -> Optional[str]:
if yaml_key not in self.unrendered_schemas:
return None

return self.unrendered_schemas[yaml_key].get(name)


@dataclass
class FixtureSourceFile(BaseSourceFile):
Expand Down
16 changes: 10 additions & 6 deletions core/dbt/contracts/graph/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1236,12 +1236,16 @@
return SourceDefinitionResource

def same_database_representation(self, other: "SourceDefinition") -> bool:
return (
self.database == other.database
and self.schema == other.schema
and self.identifier == other.identifier
and True
)

# preserve legacy behaviour -- use potentially rendered database
if get_flags().state_modified_compare_more_unrendered_values is False:
same_database = self.database == other.database
same_schema = self.schema == other.schema
else:
same_database = self.unrendered_database == other.unrendered_database
same_schema = self.unrendered_schema == other.unrendered_schema

Check warning on line 1246 in core/dbt/contracts/graph/nodes.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/contracts/graph/nodes.py#L1245-L1246

Added lines #L1245 - L1246 were not covered by tests

return same_database and same_schema and self.identifier == other.identifier and True

def same_quoting(self, other: "SourceDefinition") -> bool:
return self.quoting == other.quoting
Expand Down
2 changes: 2 additions & 0 deletions core/dbt/contracts/graph/unparsed.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ class UnparsedSourceDefinition(dbtClassMixin):
tables: List[UnparsedSourceTableDefinition] = field(default_factory=list)
tags: List[str] = field(default_factory=list)
config: Dict[str, Any] = field(default_factory=dict)
unrendered_database: Optional[str] = None
unrendered_schema: Optional[str] = None

@classmethod
def validate(cls, data):
Expand Down
18 changes: 18 additions & 0 deletions core/dbt/parser/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ def get_key_dicts(self) -> Iterable[Dict[str, Any]]:
if "v" in version:
unrendered_version_configs[version["v"]] = version.get("config", {})

# For sources
unrendered_database = entry.get("database", None)
unrendered_schema = entry.get("schema", None)

# Render the data (except for tests, data_tests and descriptions).
# See the SchemaYamlRenderer
entry = self.render_entry(entry)
Expand All @@ -401,6 +405,11 @@ def get_key_dicts(self) -> Iterable[Dict[str, Any]]:
unrendered_version_config, self.key, entry["name"], version
)

if unrendered_database:
schema_file.add_unrendered_database(self.key, entry["name"], unrendered_database)
if unrendered_schema:
schema_file.add_unrendered_schema(self.key, entry["name"], unrendered_schema)

if self.schema_yaml_vars.env_vars:
self.schema_parser.manifest.env_vars.update(self.schema_yaml_vars.env_vars)
for env_var in self.schema_yaml_vars.env_vars.keys():
Expand Down Expand Up @@ -465,6 +474,15 @@ def parse(self) -> ParseResult:
source_file.source_patches.append(key)
else:
source = self._target_from_dict(UnparsedSourceDefinition, data)
# Store unrendered_database and unrendered_schema for state:modified comparisons
if isinstance(self.yaml.file, SchemaSourceFile):
source.unrendered_database = self.yaml.file.get_unrendered_database(
"sources", source.name
)
source.unrendered_schema = self.yaml.file.get_unrendered_schema(
"sources", source.name
)

self.add_source_definitions(source)
return ParseResult()

Expand Down
2 changes: 2 additions & 0 deletions core/dbt/parser/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ def parse_source(self, target: UnpatchedSourceDefinition) -> SourceDefinition:
parsed_source = SourceDefinition(
package_name=target.package_name,
database=(source.database or default_database),
unrendered_database=source.unrendered_database,
schema=(source.schema or source.name),
unrendered_schema=source.unrendered_schema,
identifier=(table.identifier or table.name),
path=target.path,
original_file_path=target.original_file_path,
Expand Down
44 changes: 44 additions & 0 deletions schemas/dbt/manifest/v12.json
Original file line number Diff line number Diff line change
Expand Up @@ -8198,6 +8198,28 @@
},
"created_at": {
"type": "number"
},
"unrendered_database": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"unrendered_schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -18101,6 +18123,28 @@
},
"created_at": {
"type": "number"
},
"unrendered_database": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"unrendered_schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
}
},
"additionalProperties": false,
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/artifacts/data/state/v12/manifest.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions tests/functional/artifacts/expected_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,8 @@ def expected_seeded_manifest(project, model_database=None, quote_model=False):
"unique_id": "source.test.my_source.my_table",
"fqn": ["test", "my_source", "my_table"],
"unrendered_config": {},
"unrendered_database": None,
"unrendered_schema": "{{ var('test_schema') }}",
"vars": {"test_schema": ANY},
},
},
Expand Down Expand Up @@ -1327,6 +1329,8 @@ def expected_references_manifest(project):
"unique_id": "source.test.my_source.my_table",
"fqn": ["test", "my_source", "my_table"],
"unrendered_config": {},
"unrendered_database": None,
"unrendered_schema": "{{ var('test_schema') }}",
"vars": {"test_schema": ANY},
},
},
Expand Down
68 changes: 60 additions & 8 deletions tests/functional/defer_state/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,14 +560,6 @@

"""

schema_source_with_env_var_as_property_yml = """
sources:
- name: jaffle_shop
database: "{{ env_var('DBT_TEST_STATE_MODIFIED') }}"
tables:
- name: customers
"""


model_with_var_in_config_sql = """
{{ config(materialized=var('DBT_TEST_STATE_MODIFIED')) }}
Expand Down Expand Up @@ -603,3 +595,63 @@
config:
materialized: "{{ ('view' if execute else 'table') }}"
"""

schema_source_with_env_var_as_database_property_yml = """
sources:
- name: jaffle_shop
database: "{{ env_var('DBT_TEST_STATE_MODIFIED') }}"
tables:
- name: customers
"""

schema_source_with_env_var_as_schema_property_yml = """
sources:
- name: jaffle_shop
database: "test"
schema: "{{ env_var('DBT_TEST_STATE_MODIFIED') }}"
tables:
- name: customers
"""

schema_source_with_updated_env_var_as_schema_property_yml = """
sources:
- name: jaffle_shop
database: "test"
schema: "updated"
tables:
- name: customers
"""

schema_source_with_jinja_as_database_property_yml = """
sources:
- name: jaffle_shop
database: "{{ ('foo' if execute else 'bar') }}"
tables:
- name: customers
"""

schema_source_with_updated_jinja_as_database_property_yml = """
sources:
- name: jaffle_shop
database: "{{ ('bar' if execute else 'foo') }}"
tables:
- name: customers
"""

schema_source_with_jinja_as_schema_property_yml = """
sources:
- name: jaffle_shop
database: "test"
schema: "{{ ('foo' if execute else 'bar') }}"
tables:
- name: customers
"""

schema_source_with_updated_jinja_as_schema_property_yml = """
sources:
- name: jaffle_shop
database: "test"
schema: "{{ ('bar' if execute else 'foo') }}"
tables:
- name: customers
"""
3 changes: 1 addition & 2 deletions tests/functional/defer_state/test_modified_state_jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ def project_config_update(self):
def update_jinja_expression_in_config(self, project):
pass

def test_change_target_jinja_if(self, project, dbt_profile_data, profiles_root):
# Generate ./state without changing target.name
def test_change_jinja_if(self, project):
run_dbt(["run"])
self.copy_state()
# Model is table when execute = True
Expand Down
Loading
Loading