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

Implementation of metadata-based freshness #796

Merged
merged 27 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e39a6e7
Draft implementation of metadata-based freshness
peterallenwebb Oct 9, 2023
010c781
Add test of metadata-based freshness mechanism
peterallenwebb Oct 9, 2023
181d984
Merge remote-tracking branch 'origin/main' into paw/metadata-freshness
peterallenwebb Oct 10, 2023
32e7044
Strengthen test case.
peterallenwebb Oct 10, 2023
0a01187
Fix some overzealous escaping.
peterallenwebb Oct 11, 2023
8e3fd10
Simplifications per review
peterallenwebb Oct 11, 2023
d909e56
Merge branch 'main' into paw/metadata-freshness
colin-rogers-dbt Oct 11, 2023
fbd0858
Merge remote-tracking branch 'origin/main' into paw/metadata-freshness
peterallenwebb Oct 11, 2023
d04431a
Update for core code review changes
peterallenwebb Oct 11, 2023
3f1ee07
Merge branch 'main' into paw/metadata-freshness
peterallenwebb Oct 11, 2023
231fe49
Repoint to main core branch before merge
peterallenwebb Oct 11, 2023
ffedcc3
Merge remote-tracking branch 'origin/main' into paw/metadata-freshness
peterallenwebb Oct 11, 2023
cd7e3c8
Temporarily skip test
peterallenwebb Oct 11, 2023
4d8647e
test using custom schema for test
colin-rogers-dbt Oct 11, 2023
cb2570f
Merge remote-tracking branch 'origin/paw/metadata-freshness' into paw…
colin-rogers-dbt Oct 11, 2023
f131751
Merge branch 'main' into paw/metadata-freshness
mikealfare Oct 11, 2023
f12d00e
use specific schema env var
colin-rogers-dbt Oct 11, 2023
61929da
use specific schema env var
colin-rogers-dbt Oct 12, 2023
bff9f6c
cleanup env var
colin-rogers-dbt Oct 12, 2023
fc47ba3
skip test_get_last_relation_modified
colin-rogers-dbt Oct 12, 2023
01baf08
remove extra whitespace
mikealfare Oct 12, 2023
ab373e9
remove Capability.TableLastModifiedMetadata: CapabilitySupport(suppor…
mikealfare Oct 12, 2023
452da8f
remove metadata.sql for CI troubleshooting
mikealfare Oct 12, 2023
aa7c2cb
remove test_get_last_relation_modified.py for CI troubleshooting
mikealfare Oct 12, 2023
c7a2d55
add non-test files back for CI troubleshooting
mikealfare Oct 12, 2023
8622ed6
add test files back for CI troubleshooting
mikealfare Oct 12, 2023
11769bd
remove run order dependency from test cases within their test class
mikealfare Oct 12, 2023
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
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20231008-195410.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Add support for checking table-last-modified by metadata
time: 2023-10-08T19:54:10.503476-04:00
custom:
Author: peterallenwebb
Issue: "785"
31 changes: 30 additions & 1 deletion dbt/adapters/snowflake/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@

import agate

from dbt.adapters.base.impl import AdapterConfig, ConstraintSupport # type: ignore
from dbt.adapters.base.impl import (
AdapterConfig,
Capability,
CapabilitySupport,
ConstraintSupport,
Support,
) # type: ignore
from dbt.adapters.base.meta import available
from dbt.adapters.sql import SQLAdapter # type: ignore
from dbt.adapters.sql.impl import (
Expand Down Expand Up @@ -49,6 +55,17 @@ class SnowflakeAdapter(SQLAdapter):
ConstraintType.foreign_key: ConstraintSupport.NOT_ENFORCED,
}

_capabilities: Dict[Capability, CapabilitySupport] = {
peterallenwebb marked this conversation as resolved.
Show resolved Hide resolved
Capability.TableLastModifiedMetadata: CapabilitySupport(
capability=Capability.TableLastModifiedMetadata,
support=Support.Full,
),
Capability.SchemaMetadataByRelations: CapabilitySupport(
capability=Capability.SchemaMetadataByRelations,
support=Support.NotImplemented,
),
}

@classmethod
def date_function(cls):
return "CURRENT_TIMESTAMP()"
Expand Down Expand Up @@ -259,3 +276,15 @@ def valid_incremental_strategies(self):
def debug_query(self):
"""Override for DebugTask method"""
self.execute("select 1 as id")

def capabilities(self) -> List[CapabilitySupport]:
peterallenwebb marked this conversation as resolved.
Show resolved Hide resolved
return [c for c in self._capabilities.values()]

def capability_support(self, capability: Capability) -> CapabilitySupport:
peterallenwebb marked this conversation as resolved.
Show resolved Hide resolved
if capability in self._capabilities:
return self._capabilities[capability]
else:
return CapabilitySupport(
capability=capability,
support=Support.Unknown,
)
19 changes: 19 additions & 0 deletions dbt/include/snowflake/macros/metadata.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% macro snowflake__get_relation_last_modified(information_schema, relations) -%}

{%- call statement('last_modified', fetch_result=True) -%}
select table_schema as schema,
mikealfare marked this conversation as resolved.
Show resolved Hide resolved
table_name as identifier,
last_altered as last_modified,
{{ current_timestamp() }} as snapshotted_at
from {{ information_schema }}.tables
where (
peterallenwebb marked this conversation as resolved.
Show resolved Hide resolved
{%- for relation in relations -%}
mikealfare marked this conversation as resolved.
Show resolved Hide resolved
(upper(table_schema) = upper('{{ relation.schema }}') and
upper(table_name) = upper('{{ relation.identifier }}')){%- if not loop.last %} or {% endif -%}
{%- endfor -%}
)
{%- endcall -%}

{{ return(load_result('last_modified')) }}

{% endmacro %}
2 changes: 1 addition & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# install latest changes in dbt-core
# TODO: how to automate switching from develop to version branches?
git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-core&subdirectory=core
git+https://github.com/dbt-labs/dbt-core.git@paw%2Fmetadata-freshness#egg=dbt-core&subdirectory=core
peterallenwebb marked this conversation as resolved.
Show resolved Hide resolved
git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-tests-adapter&subdirectory=tests/adapter

# if version 1.x or greater -> pin to major version
Expand Down
46 changes: 46 additions & 0 deletions tests/functional/adapter/test_get_last_relation_modified.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import os
import pytest

from dbt.cli.main import dbtRunner


freshness_via_metadata_schema_yml = """version: 2
sources:
- name: test_source
freshness:
warn_after: {count: 10, period: hour}
error_after: {count: 1, period: day}
schema: "{{ env_var('DBT_TEST_SCHEMA_NAME_VARIABLE') }}"
tables:
- name: test_table
"""


class TestGetLastRelationModified:
peterallenwebb marked this conversation as resolved.
Show resolved Hide resolved
mikealfare marked this conversation as resolved.
Show resolved Hide resolved
@pytest.fixture(scope="class", autouse=True)
def set_env_vars(self, project):
os.environ["DBT_TEST_SCHEMA_NAME_VARIABLE"] = project.test_schema
yield
del os.environ["DBT_TEST_SCHEMA_NAME_VARIABLE"]

@pytest.fixture(scope="class")
def models(self):
return {"schema.yml": freshness_via_metadata_schema_yml}

def test_get_last_relation_modified(self, project, set_env_vars):
project.run_sql(
f"create table {project.test_schema}.test_table (id integer autoincrement, name varchar(100) not null);"
)

warning_or_error = False

def probe(e):
nonlocal warning_or_error
if e.info.level in ["warning", "error"]:
warning_or_error = True

runner = dbtRunner(callbacks=[probe])
runner.invoke(["source", "freshness"])

# The 'source freshness' command should succeed without warnings or errors.
assert not warning_or_error
Loading