-
Notifications
You must be signed in to change notification settings - Fork 235
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dbt Constraints / model contracts (#574)
* Add support for constraints in Spark * Add tests for constraints * Update requirements for CI to pass * Update dispatched macro with argument * Use spark decorator for tests * Update test to remove unsupported constraints * Allow multiple queries to be sent * Revert change on splitting satements in `execute` * Add `call statement` for table with constraints * Add checks when the split by `;` is empty * Fix typo in JInja variable name * Rename `constraints` to `constraints_check` * Support constraints with `alter` statements * Changie entry * Fix missing `endif` * Remove get_columns_spec_ddl as we use alter * Remove unused dispatch macro * Update dispatched macro * Update tests to work with `alter` approach * Make tests valid for databricks only for delta * Try other way to call tests * Add schema info * Remove wrong argument to test * Use new testing framework * Add check on column names and order * Check only when constraints enabled * Remove config nesting * constraint_check is not a list * Fix CICD * Typo * Only allow not null * Update expected SQL to the Spark one * Make file_format delta * Try this * Check for earlier part of error message * Check for any rather than all error messages * Reset to dbt-core main --------- Co-authored-by: Sung Won Chung <sungwonchung3@gmail.com> Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com> Co-authored-by: Michelle Ark <michelle.ark@dbtlabs.com>
- Loading branch information
1 parent
6f7307b
commit b3f6558
Showing
4 changed files
with
120 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
kind: Features | ||
body: 'Support for data types constraints in Spark following the dbt Core feature | ||
#6271' | ||
time: 2023-01-30T12:58:55.972992+01:00 | ||
custom: | ||
Author: b-per | ||
Issue: "558" | ||
PR: "574" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import pytest | ||
from dbt.tests.util import relation_from_name | ||
from dbt.tests.adapter.constraints.test_constraints import ( | ||
BaseConstraintsColumnsEqual, | ||
BaseConstraintsRuntimeEnforcement | ||
) | ||
|
||
# constraints are enforced via 'alter' statements that run after table creation | ||
_expected_sql_spark = """ | ||
create or replace table {0} | ||
using delta | ||
as | ||
select | ||
1 as id, | ||
'blue' as color, | ||
cast('2019-01-01' as date) as date_day | ||
""" | ||
|
||
@pytest.mark.skip_profile('spark_session', 'apache_spark') | ||
class TestSparkConstraintsColumnsEqual(BaseConstraintsColumnsEqual): | ||
pass | ||
|
||
@pytest.mark.skip_profile('spark_session', 'apache_spark') | ||
class TestSparkConstraintsRuntimeEnforcement(BaseConstraintsRuntimeEnforcement): | ||
@pytest.fixture(scope="class") | ||
def project_config_update(self): | ||
return { | ||
"models": { | ||
"+file_format": "delta", | ||
} | ||
} | ||
|
||
@pytest.fixture(scope="class") | ||
def expected_sql(self, project): | ||
relation = relation_from_name(project.adapter, "my_model") | ||
return _expected_sql_spark.format(relation) | ||
|
||
# On Spark/Databricks, constraints are applied *after* the table is replaced. | ||
# We don't have any way to "rollback" the table to its previous happy state. | ||
# So the 'color' column will be updated to 'red', instead of 'blue'. | ||
@pytest.fixture(scope="class") | ||
def expected_color(self): | ||
return "red" | ||
|
||
@pytest.fixture(scope="class") | ||
def expected_error_messages(self): | ||
return [ | ||
"violate the new CHECK constraint", | ||
"DELTA_NEW_CHECK_CONSTRAINT_VIOLATION", | ||
"violate the new NOT NULL constraint", | ||
] | ||
|
||
def assert_expected_error_messages(self, error_message, expected_error_messages): | ||
# This needs to be ANY instead of ALL | ||
# The CHECK constraint is added before the NOT NULL constraint | ||
# and different connection types display/truncate the error message in different ways... | ||
assert any(msg in error_message for msg in expected_error_messages) |