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

Implement get_catalog_for_single_relation macro #1064

Merged
merged 29 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
361d196
Allow enabling/disabling stats collection on catalog table using env var
aranke May 16, 2024
4970ddf
Implement get_relation_metadata macro
aranke May 28, 2024
bfe8cb1
Merge branch 'main' into catalog_enable_stats
aranke May 28, 2024
be990e1
Discard changes to dbt/include/snowflake/macros/catalog.sql
aranke May 28, 2024
1783849
Import artifacts from dbt_common
aranke May 29, 2024
d19e3ef
fix dbt_common import
aranke May 29, 2024
2213a16
Use get_relation_metadata from dbt-common
aranke May 29, 2024
efb3595
Update Fixes-20240516-224134.yaml
aranke May 29, 2024
1944fb7
use snowflakerelation
aranke May 29, 2024
8fa4f1d
add broken test
aranke Jun 5, 2024
f76e29b
wip
aranke Jun 6, 2024
4f5336f
Merge branch 'main' into catalog_enable_stats
colin-rogers-dbt Jun 7, 2024
6e09133
add test for get_catalog_for_single_relation
aranke Jun 11, 2024
f7892e1
Merge branch 'main' into catalog_enable_stats
aranke Jun 11, 2024
a30cc8c
Merge branch 'main' into catalog_enable_stats
aranke Jun 12, 2024
9cf3497
wip
aranke Jun 18, 2024
8bd2b11
wip
aranke Jun 18, 2024
b501d16
merge from main
aranke Jun 18, 2024
ab51351
hardcode macro name
aranke Jun 18, 2024
2f4510b
fix docs_generate test
aranke Jun 18, 2024
5aacd01
address pr comments
aranke Jun 18, 2024
126ba32
update changie, add type sigs
aranke Jun 18, 2024
a6cc1c7
Use enum values for comparison
aranke Jun 18, 2024
943be20
remove mv
aranke Jun 18, 2024
7a3ea26
Discard changes to dev-requirements.txt
aranke Jun 18, 2024
a269ae2
Discard changes to setup.py
aranke Jun 18, 2024
4c014d7
Merge branch 'main' into catalog_enable_stats
mikealfare Jun 20, 2024
1a734c4
Merge branch 'main' into catalog_enable_stats
mikealfare Jun 20, 2024
55ee5c3
Bump pins on dbt-common and dbt-adapters
aranke Jun 21, 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
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20240516-224134.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: Implement get_relation_metadata macro
aranke marked this conversation as resolved.
Show resolved Hide resolved
time: 2024-05-16T22:41:34.256095+01:00
custom:
Author: aranke
Issue: "1048"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,4 @@ venv/

# vscode
.vscode/
.venv/
aranke marked this conversation as resolved.
Show resolved Hide resolved
97 changes: 92 additions & 5 deletions dbt/adapters/snowflake/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Mapping, Any, Optional, List, Union, Dict, FrozenSet, Tuple

import agate

from dbt.adapters.base import BaseRelation
from dbt.adapters.base.impl import AdapterConfig, ConstraintSupport
from dbt.adapters.base.meta import available
from dbt.adapters.capability import CapabilityDict, CapabilitySupport, Support, Capability
Expand All @@ -11,14 +11,23 @@
LIST_SCHEMAS_MACRO_NAME,
LIST_RELATIONS_MACRO_NAME,
)

from dbt.adapters.snowflake import SnowflakeConnectionManager
from dbt.adapters.snowflake import SnowflakeRelation
from dbt.adapters.snowflake import SnowflakeColumn
from dbt_common.contracts.constraints import ConstraintType
from dbt_common.contracts.metadata import (
TableMetadata,
StatsDict,
StatsItem,
CatalogTable,
ColumnMetadata,
)
from dbt_common.exceptions import CompilationError, DbtDatabaseError, DbtRuntimeError
from dbt_common.utils import filter_null_values

from dbt.adapters.snowflake import SnowflakeColumn
from dbt.adapters.snowflake import SnowflakeConnectionManager
from dbt.adapters.snowflake import SnowflakeRelation

SHOW_OBJECT_METADATA_MACRO_NAME = "snowflake__show_object_metadata"


@dataclass
class SnowflakeConfig(AdapterConfig):
Expand Down Expand Up @@ -54,6 +63,7 @@ class SnowflakeAdapter(SQLAdapter):
Capability.SchemaMetadataByRelations: CapabilitySupport(support=Support.Full),
Capability.TableLastModifiedMetadata: CapabilitySupport(support=Support.Full),
Capability.TableLastModifiedMetadataBatch: CapabilitySupport(support=Support.Full),
Capability.GetCatalogForSingleRelation: CapabilitySupport(support=Support.Full),
}
)

Expand Down Expand Up @@ -129,6 +139,83 @@ def get_columns_in_relation(self, relation):
else:
raise

def _show_object_metadata(self, relation):
aranke marked this conversation as resolved.
Show resolved Hide resolved
try:
kwargs = {"relation": relation}
results = self.execute_macro(SHOW_OBJECT_METADATA_MACRO_NAME, kwargs=kwargs)
except DbtDatabaseError as exc:
# If we don't have permissions to the object, return empty
if "Object does not exist" in str(exc):
return None
else:
# If we don't get any results, return empty
if len(results) == 0:
return None

return results

def get_catalog_for_single_relation(self, relation: BaseRelation) -> Optional[CatalogTable]:
object_metadata = self._show_object_metadata(relation)

if object_metadata:
aranke marked this conversation as resolved.
Show resolved Hide resolved
row = object_metadata[0]

is_dynamic = row.get("is_dynamic")
kind = row.get("kind")

if is_dynamic == "YES" and kind == "BASE TABLE":
table_type = "DYNAMIC TABLE"
else:
table_type = kind

table_metadata = TableMetadata(
type=table_type,
schema=row.get("schema_name"),
name=row.get("name"),
database=row.get("database_name"),
comment=row.get("comment"),
owner=row.get("owner"),
)

stats_dict: StatsDict = {
"has_stats": StatsItem(
id="has_stats",
label="Has Stats?",
value=True,
include=False,
description="Indicates whether there are statistics for this table",
),
"row_count": StatsItem(
id="row_count",
label="Row Count",
value=row.get("rows"),
include=True,
description="Number of rows in the table as reported by Snowflake",
),
"bytes": StatsItem(
id="bytes",
label="Approximate Size",
value=row.get("bytes"),
include=True,
description="Size of the table as reported by Snowflake",
),
}

catalog_columns = {}
columns_metadata = self.get_columns_in_relation(relation)

for i, c in enumerate(columns_metadata):
aranke marked this conversation as resolved.
Show resolved Hide resolved
name = c.column
catalog_columns[name] = ColumnMetadata(type=c.dtype, index=i + 1, name=name)

return CatalogTable(
metadata=table_metadata,
columns=catalog_columns,
stats=stats_dict,
)
else:
return None

def list_relations_without_caching(
self, schema_relation: SnowflakeRelation
) -> List[SnowflakeRelation]:
Expand Down
9 changes: 9 additions & 0 deletions dbt/include/snowflake/macros/adapters.sql
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@
{% do return(columns) %}
{% endmacro %}

{% macro snowflake__show_object_metadata(relation) %}
{%- set sql -%}
show objects like '{{ relation.identifier }}' in {{ relation.database }}.{{ relation.schema }} limit 1
aranke marked this conversation as resolved.
Show resolved Hide resolved
{%- endset -%}

{%- set result = run_query(sql) -%}
{{ return(result) }}
{% endmacro %}

{% macro snowflake__list_schemas(database) -%}
{# 10k limit from here: https://docs.snowflake.net/manuals/sql-reference/sql/show-schemas.html#usage-notes #}
{% set maximum = 10000 %}
Expand Down
6 changes: 3 additions & 3 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# install latest changes in dbt-core
git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-core&subdirectory=core
git+https://github.com/dbt-labs/dbt-adapters.git
git+https://github.com/dbt-labs/dbt-adapters.git#subdirectory=dbt-tests-adapter
git+https://github.com/dbt-labs/dbt-common.git
git+https://github.com/dbt-labs/dbt-adapters.git@get_relation_metadata
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to revert prior to merging.

git+https://github.com/dbt-labs/dbt-adapters.git@get_relation_metadata#subdirectory=dbt-tests-adapter
git+https://github.com/dbt-labs/dbt-common.git@main

# dev
ipdb~=0.13.13
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ def _plugin_version() -> str:
packages=find_namespace_packages(include=["dbt", "dbt.*"]),
include_package_data=True,
install_requires=[
"dbt-common>=1.0.4,<2.0",
"dbt-adapters>=1.1.1,<2.0",
# "dbt-common>=1.2.0,<2.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to revert prior to merging. Also, we need a new lower bound on dbt-adapters and dbt-common for this new feature.

"dbt-adapters @ git+https://github.com/dbt-labs/dbt-adapters.git@get_relation_metadata",
"snowflake-connector-python[secure-local-storage]~=3.0",
# add dbt-core to ensure backwards compatibility of installation, this is not a functional dependency
"dbt-core>=1.8.0",
Expand Down
7 changes: 7 additions & 0 deletions tests/functional/adapter/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
from dbt.tests.adapter.basic.test_singular_tests_ephemeral import (
BaseSingularTestsEphemeral,
)
from dbt.tests.adapter.basic.test_get_catalog_for_single_relation import (
BaseGetCatalogForSingleRelation,
)
from dbt.tests.adapter.basic.test_empty import BaseEmpty
from dbt.tests.adapter.basic.test_ephemeral import BaseEphemeral
from dbt.tests.adapter.basic.test_incremental import BaseIncremental
Expand All @@ -25,6 +28,10 @@ class TestSingularTestsSnowflake(BaseSingularTests):
pass


class TestGetCatalogForSingleRelationSnowflake(BaseGetCatalogForSingleRelation):
pass
aranke marked this conversation as resolved.
Show resolved Hide resolved


class TestSingularTestsEphemeralSnowflake(BaseSingularTestsEphemeral):
pass

Expand Down
5 changes: 4 additions & 1 deletion tests/unit/mock_adapter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from contextlib import contextmanager
from unittest import mock

from dbt.adapters.base import BaseAdapter
from contextlib import contextmanager


def adapter_factory():
Expand Down Expand Up @@ -33,6 +33,9 @@ def rename_relation(self, *args, **kwargs):
def get_columns_in_relation(self, *args, **kwargs):
return self.responder.get_columns_in_relation(*args, **kwargs)

def get_catalog_for_single_relation(self, *args, **kwargs):
return self.responder.get_catalog_for_single_relation(*args, **kwargs)

def expand_column_types(self, *args, **kwargs):
return self.responder.expand_column_types(*args, **kwargs)

Expand Down
Loading