-
Notifications
You must be signed in to change notification settings - Fork 178
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
dbt Constraints / model contracts #341
Conversation
Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see the dbt-snowflake contributing guide. |
I should have communicated better that my PR #6271 actually uses the below config. version: 2
models:
- name: constraints_example
docs:
node_color: black
config:
constraints_enabled: true
columns:
- name: id
data_type: integer
description: hello
constraints: ['not null','primary key']
check: id > 0
tests:
- unique
- name: color
data_type: string
- name: date_day
data_type: date
|
{% set constraints = col['constraint'] -%} | ||
{%- set checks = col['checks'] -%} | ||
{%- if checks -%} | ||
{{exceptions.warn("We noticed you have `checks` in your configs, these are NOT compatible with Snowflake and will be ignored")}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you show me a screenshot of the warning message working in your terminal? I couldn't get it to pop up on mine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it to work by copying your code to my branch. I'll figure out the pip installs later! Looks good @jtcohen6 what's your opinion on how the warning should look and where in the logs it should appear?
@joshuataylor keep your eyes on this when it's ready for local testing on your machine! |
@joshuataylor try to test this out now! |
""" | ||
|
||
|
||
class TestMaterializedWithConstraints: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a rollback to previous table test based on this: https://github.com/dbt-labs/dbt-core/pull/6271/files#diff-ace143195a2ed95e724979d70d36ca44a4177f0876f768795225994d87142da8R139
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a DDL actual == expected test based on this: https://github.com/dbt-labs/dbt-core/pull/6271/files#diff-ace143195a2ed95e724979d70d36ca44a4177f0876f768795225994d87142da8R119
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want the DDL test? I feel like any other change to create_table_as()
would then require updating the tests for something unrelated.
I actually wanted to avoid a test checking the DDL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on an internal slack thread, you don't need the DDL test, but the rollback test remains to be needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I can create a rollback test. Because this PR leverages Snowflake's ability to set constraints as part of the CTAS statement I think that this use case is already covered by the existing CTAS tests but it is not too difficult for me to add another one here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks looks great!
Sorry I've had family issues over the past week or so, so haven't had a chance to check this out yet. I'm planning on checking this out over the next few days, but obviously with being the holiday season I won't expect an immediate reply on feedback 🚀 |
{%- endfor %} | ||
) | ||
{%- if ns.at_least_one_check -%} | ||
{{exceptions.warn("We noticed you have `check` configs, these are NOT compatible with Snowflake and will be ignored")}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe link to https://docs.snowflake.com/en/sql-reference/constraints-overview.html ?
Maybe the wording can be similar to what they have?
Snowflake supports defining and maintaining constraints, but does not enforce them, except for NOT NULL constraints, which are always enforced.
@@ -0,0 +1,18 @@ | |||
{% macro snowflake__get_columns_spec_ddl() %} | |||
{# loop through user_provided_columns to create DDL with data types and constraints #} | |||
{% if config.get('constraints_enabled', False) %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, nice work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this if statement to adapters.sql
similar to this: https://github.com/dbt-labs/dbt-core/pull/6271/files#diff-7246f19f4d12042d172ac61b3d0c4564ea27dd8825870b35425ede1ea41625dbR28
This PR brings me such joy 😍. 2023 is going to be the year we stop having to cast everything in SQL (so it doesn't randomly change 😬 ) and it'll work on a YAML level. 🎉🎉🎉 |
{% for i in user_provided_columns -%} | ||
{%- set col = user_provided_columns[i] -%} | ||
{% set constraints = col['constraints'] -%} | ||
{%- set ns.at_least_one_check = ns.at_least_one_check or col['check'] %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{%- set ns.at_least_one_check = ns.at_least_one_check or col['check'] %} | |
{%- set ns.at_least_one_check = ns.at_least_one_check or col['constraints_check'] %} |
Do a find and replace on all check configs
in all files to be constraints_check
by name.
Tests are failing due to Snowflake columns being internally stored in uppercase. |
Co-authored-by: Sung Won Chung <sungwonchung3@gmail.com>
bd8ca0d
to
f63c639
Compare
I know it's not |
@joshuataylor It's official. You can give this a rougher test drive now :) |
Linked to the dbt-core issues dbt-labs/dbt-core#6079 and dbt-labs/dbt-core#6079
These changes, along with the dbt-Core ones, allow defining column types and constraints on columns in Snowflake.
Description
unique
,not null
,primary key
andforeign key
not null
(and thenot null
property ofprimary key
) are actually checked today in Snowflake. There rest of the constraints are purely metadata ones, not verified when inserting datachecks
, I don't think that those are supported in Snowflake todayCTA
failsRelated Core/Adapter Pull Requests
Example of behavior
The following
jaffle_shop
examplegenerates the following SQL:
Checklist
changie new
to create a changelog entry