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

Bumping version to 1.5.0rc2, Add model contracts #286

Merged
merged 4 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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-20230419-115208.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Features
body: Add model contracts
time: 2023-04-19T11:52:08.343309+02:00
custom:
Author: damian3031
Issue: "284"
PR: "286"
2 changes: 1 addition & 1 deletion dbt/adapters/trino/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = "1.4.2"
version = "1.5.0rc2"
4 changes: 4 additions & 0 deletions dbt/adapters/trino/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,3 +508,7 @@ def execute(self, sql, auto_begin=False, fetch=False):
status = self.get_response(cursor)
table = self.get_result_from_cursor(cursor)
return status, table

@classmethod
def data_type_code_to_name(cls, type_code) -> str:
return type_code.split("(")[0].upper()
11 changes: 10 additions & 1 deletion dbt/adapters/trino/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
from typing import Dict, Optional

import agate
from dbt.adapters.base.impl import AdapterConfig
from dbt.adapters.base.impl import AdapterConfig, ConstraintSupport
from dbt.adapters.sql import SQLAdapter
from dbt.contracts.graph.nodes import ConstraintType
from dbt.exceptions import DbtDatabaseError

from dbt.adapters.trino import TrinoColumn, TrinoConnectionManager, TrinoRelation
Expand All @@ -21,6 +22,14 @@ class TrinoAdapter(SQLAdapter):
ConnectionManager = TrinoConnectionManager
AdapterSpecificConfigs = TrinoConfig

CONSTRAINT_SUPPORT = {
ConstraintType.check: ConstraintSupport.NOT_SUPPORTED,
ConstraintType.not_null: ConstraintSupport.NOT_SUPPORTED,
Copy link
Member

Choose a reason for hiding this comment

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

If this works in iceberg, it would be nice to support this.

Copy link
Member Author

Choose a reason for hiding this comment

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

I added new commit with support for not-null constraint. All tests needed to be marked with @pytest.mark.iceberg now, as catalog memory does not support non-null column

ConstraintType.unique: ConstraintSupport.NOT_SUPPORTED,
ConstraintType.primary_key: ConstraintSupport.NOT_SUPPORTED,
ConstraintType.foreign_key: ConstraintSupport.NOT_SUPPORTED,
}

@classmethod
def date_function(cls):
return "datenow()"
Expand Down
34 changes: 30 additions & 4 deletions dbt/include/trino/macros/adapters.sql
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,33 @@

{% macro trino__create_table_as(temporary, relation, sql) -%}
{%- set _properties = config.get('properties') -%}
create table {{ relation }}

{%- set contract_config = config.get('contract') -%}
{%- if contract_config.enforced -%}

create table
{{ relation }}
{{ get_table_columns_and_constraints() }}
{{ get_assert_columns_equivalent(sql) }}
{%- set sql = get_select_subquery(sql) %}
Comment on lines +98 to +102
Copy link
Member

Choose a reason for hiding this comment

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

Please create an issue to investigate type specification in CTAS in Trino. We should validate if this is supported by the SQL spec or not because this way won't allow to hot swap the table using CREATE OR REPLACE.

Copy link
Member

Choose a reason for hiding this comment

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

Also I would prefer this to be implemented with DESCRIBE OUTPUT instead of splitting into a CT and INSERT.

Copy link
Member Author

Choose a reason for hiding this comment

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

As discussed offline, let's keep current implementation and I'll create issue which you mentioned.

{{ properties(_properties) }}
as (
{{ sql }}
);
;

insert into {{ relation }}
(
{{ sql }}
)
;

{%- else %}

create table {{ relation }}
{{ properties(_properties) }}
as (
{{ sql }}
);

{%- endif %}
{% endmacro %}


Expand All @@ -108,6 +130,10 @@
{% endif %}
create or replace view
{{ relation }}
{%- set contract_config = config.get('contract') -%}
{%- if contract_config.enforced -%}
{{ get_assert_columns_equivalent(sql) }}
{%- endif %}
security {{ view_security }}
as
{{ sql }}
Expand Down
2 changes: 1 addition & 1 deletion dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
dbt-tests-adapter~=1.4.5
dbt-tests-adapter~=1.5.0rc2
mypy==1.2.0 # patch updates have historically introduced breaking changes
pre-commit~=3.2
pytest~=7.2
Expand Down
119 changes: 119 additions & 0 deletions tests/functional/adapter/constraints/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# model breaking constraints
trino_model_char_value_to_int_column = """
{{
config(
materialized = "table"
)
}}

select
-- char value for 'id', which is integer type
'char_value' as id,
-- change the color as well (to test rollback)
'red' as color,
'2019-01-01' as date_day
"""

trino_model_schema_yml = """
version: 2
models:
- name: my_model
config:
contract:
enforced: true
columns:
- name: id
quote: true
data_type: integer
description: hello
constraints:
- type: check
expression: (id > 0)
tests:
- unique
- name: color
data_type: varchar
- name: date_day
data_type: varchar
- name: my_model_error
config:
contract:
enforced: true
columns:
- name: id
data_type: integer
description: hello
constraints:
- type: check
expression: (id > 0)
tests:
- unique
- name: color
data_type: varchar
- name: date_day
data_type: varchar
- name: my_model_wrong_order
config:
contract:
enforced: true
columns:
- name: id
data_type: integer
description: hello
constraints:
- type: check
expression: (id > 0)
tests:
- unique
- name: color
data_type: varchar
- name: date_day
data_type: varchar
- name: my_model_wrong_name
config:
contract:
enforced: true
columns:
- name: id
data_type: integer
description: hello
constraints:
- type: check
expression: (id > 0)
tests:
- unique
- name: color
data_type: varchar
- name: date_day
data_type: varchar
"""

trino_constrained_model_schema_yml = """
version: 2
models:
- name: my_model
config:
contract:
enforced: true
constraints:
- type: check
expression: (id > 0)
- type: primary_key
columns: [ id ]
- type: unique
columns: [ color, date_day ]
name: strange_uniqueness_requirement
columns:
- name: id
quote: true
data_type: integer
description: hello
constraints:
- type: not_null
tests:
- unique
- name: color
data_type: varchar
- name: date_day
data_type: varchar
"""
Loading