Skip to content

Commit dcd85fb

Browse files
jtcohen6dbeatty10
andauthored
Use built-in adapter functionality for datatypes (#586)
* Use built-in adapter functionality for datatypes * Experiment with adding functional tests * Try to fix pip install * Missing pytest plugin * Refactor tests, passing on BQ * Refactor again * Revert bq target changes * Migrate pieces into core + plugins * Revert accidental changes to bash files * Some code cleanup * Restore needed import. Add speedup * Add back imports from `main` branches Co-authored-by: Doug Beatty <doug.beatty@dbtlabs.com>
1 parent 02a8133 commit dcd85fb

13 files changed

+260
-86
lines changed

dev-requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-postgres&subdirectory=plugi
66
git+https://github.com/dbt-labs/dbt-redshift.git
77
git+https://github.com/dbt-labs/dbt-snowflake.git
88
git+https://github.com/dbt-labs/dbt-bigquery.git
9+
pytest-xdist

macros/cross_db_utils/datatypes.sql

+15-47
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,67 @@
1+
{# These macros have been moved into dbt-core #}
2+
{# Here for backwards compatibility ONLY #}
3+
14
{# string ------------------------------------------------- #}
25

36
{%- macro type_string() -%}
4-
{{ return(adapter.dispatch('type_string', 'dbt_utils')()) }}
7+
{{ return(adapter.dispatch('type_string', 'dbt_utils')()) }}
58
{%- endmacro -%}
69

710
{% macro default__type_string() %}
8-
string
11+
{{ return(adapter.dispatch('type_string', 'dbt')()) }}
912
{% endmacro %}
1013

11-
{%- macro redshift__type_string() -%}
12-
varchar
13-
{%- endmacro -%}
14-
15-
{% macro postgres__type_string() %}
16-
varchar
17-
{% endmacro %}
18-
19-
{% macro snowflake__type_string() %}
20-
varchar
21-
{% endmacro %}
22-
23-
2414

2515
{# timestamp ------------------------------------------------- #}
2616

2717
{%- macro type_timestamp() -%}
28-
{{ return(adapter.dispatch('type_timestamp', 'dbt_utils')()) }}
18+
{{ return(adapter.dispatch('type_timestamp', 'dbt_utils')()) }}
2919
{%- endmacro -%}
3020

3121
{% macro default__type_timestamp() %}
32-
timestamp
33-
{% endmacro %}
34-
35-
{% macro postgres__type_timestamp() %}
36-
timestamp without time zone
37-
{% endmacro %}
38-
39-
{% macro snowflake__type_timestamp() %}
40-
timestamp_ntz
22+
{{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}
4123
{% endmacro %}
4224

4325

4426
{# float ------------------------------------------------- #}
4527

4628
{%- macro type_float() -%}
47-
{{ return(adapter.dispatch('type_float', 'dbt_utils')()) }}
29+
{{ return(adapter.dispatch('type_float', 'dbt_utils')()) }}
4830
{%- endmacro -%}
4931

5032
{% macro default__type_float() %}
51-
float
33+
{{ return(adapter.dispatch('type_float', 'dbt')()) }}
5234
{% endmacro %}
5335

54-
{% macro bigquery__type_float() %}
55-
float64
56-
{% endmacro %}
5736

5837
{# numeric ------------------------------------------------ #}
5938

6039
{%- macro type_numeric() -%}
61-
{{ return(adapter.dispatch('type_numeric', 'dbt_utils')()) }}
40+
{{ return(adapter.dispatch('type_numeric', 'dbt_utils')()) }}
6241
{%- endmacro -%}
6342

6443
{% macro default__type_numeric() %}
65-
numeric(28, 6)
66-
{% endmacro %}
67-
68-
{% macro bigquery__type_numeric() %}
69-
numeric
44+
{{ return(adapter.dispatch('type_numeric', 'dbt')()) }}
7045
{% endmacro %}
7146

7247

7348
{# bigint ------------------------------------------------- #}
7449

7550
{%- macro type_bigint() -%}
76-
{{ return(adapter.dispatch('type_bigint', 'dbt_utils')()) }}
51+
{{ return(adapter.dispatch('type_bigint', 'dbt_utils')()) }}
7752
{%- endmacro -%}
7853

7954
{% macro default__type_bigint() %}
80-
bigint
55+
{{ return(adapter.dispatch('type_bigint', 'dbt')()) }}
8156
{% endmacro %}
8257

83-
{% macro bigquery__type_bigint() %}
84-
int64
85-
{% endmacro %}
8658

8759
{# int ------------------------------------------------- #}
8860

8961
{%- macro type_int() -%}
90-
{{ return(adapter.dispatch('type_int', 'dbt_utils')()) }}
62+
{{ return(adapter.dispatch('type_int', 'dbt_utils')()) }}
9163
{%- endmacro -%}
9264

9365
{% macro default__type_int() %}
94-
int
95-
{% endmacro %}
96-
97-
{% macro bigquery__type_int() %}
98-
int64
66+
{{ return(adapter.dispatch('type_int', 'dbt')()) }}
9967
{% endmacro %}

run_functional_test.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/bin/bash
22

3-
python3 -m pytest tests/functional --profile $1
3+
python3 -m pytest tests/functional -n4 --profile $1

tests/conftest.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66

77
def pytest_addoption(parser):
8-
parser.addoption("--profile", action="store", default="apache_spark", type=str)
8+
parser.addoption("--profile", action="store", default="postgres", type=str)
99

1010

11-
# Using @pytest.mark.skip_adapter('apache_spark') uses the 'skip_by_adapter_type'
11+
# Using @pytest.mark.skip_profile('postgres') uses the 'skip_by_profile_type'
1212
# autouse fixture below
1313
def pytest_configure(config):
1414
config.addinivalue_line(

tests/functional/cross_db_utils/base_cross_db_macro.py

-30
This file was deleted.

tests/functional/cross_db_utils/fixture_cross_db_macro.py

-6
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import os
2+
import pytest
3+
from dbt.tests.util import run_dbt, check_relations_equal, get_relation_columns
4+
from dbt.tests.adapter.utils.data_types.base_data_type_macro import BaseDataTypeMacro
5+
6+
class BaseDbtUtilsBackCompat(BaseDataTypeMacro):
7+
# install this repo as a package
8+
@pytest.fixture(scope="class")
9+
def packages(self):
10+
return {"packages": [{"local": os.getcwd()}]}
11+
12+
# call the macros from the 'dbt_utils' namespace
13+
# instead of the unspecified / global namespace
14+
def macro_namespace(self):
15+
return "dbt_utils"
16+
17+
# actual test sequence needs to run 'deps' first
18+
def test_check_types_assert_match(self, project):
19+
run_dbt(['deps'])
20+
super().test_check_types_assert_match(project)
21+
22+
23+
class BaseLegacyDataTypeMacro(BaseDbtUtilsBackCompat):
24+
def assert_columns_equal(self, project, expected_cols, actual_cols):
25+
# we need to be a little more lenient when mapping between 'legacy' and 'new' types that are equivalent
26+
# e.g. 'character varying' and 'text'
27+
if expected_cols == actual_cols:
28+
# cool, no need for jank
29+
pass
30+
else:
31+
# this is pretty janky
32+
# our goal here: reasonable confidence that the switch from the legacy version of the dbt_utils.type_{X} macro,
33+
# and the new version, will not constitute a breaking change for end users
34+
for (expected_col, actual_col) in zip(expected_cols, actual_cols):
35+
expected = project.adapter.Column(*expected_col)
36+
actual = project.adapter.Column(*actual_col)
37+
print(f"Subtle type difference detected: {expected.data_type} vs. {actual.data_type}")
38+
if any((
39+
expected.is_string() and actual.is_string(),
40+
expected.is_float() and actual.is_float(),
41+
expected.is_integer() and actual.is_integer(),
42+
expected.is_numeric() and actual.is_numeric(),
43+
)):
44+
pytest.xfail()
45+
else:
46+
pytest.fail()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import pytest
2+
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
3+
from dbt.tests.adapter.utils.data_types.test_type_bigint import BaseTypeBigInt
4+
5+
6+
class TestTypeBigInt(BaseDbtUtilsBackCompat, BaseTypeBigInt):
7+
pass
8+
9+
10+
# previous dbt_utils code
11+
macros__legacy_sql = """
12+
{% macro default__type_bigint() %}
13+
bigint
14+
{% endmacro %}
15+
16+
{% macro bigquery__type_bigint() %}
17+
int64
18+
{% endmacro %}
19+
"""
20+
21+
class TestTypeBigIntLegacy(BaseLegacyDataTypeMacro, BaseTypeBigInt):
22+
@pytest.fixture(scope="class")
23+
def macros(self):
24+
return {
25+
"legacy.sql": macros__legacy_sql
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import pytest
2+
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
3+
from dbt.tests.adapter.utils.data_types.test_type_float import BaseTypeFloat
4+
5+
6+
class TestTypeFloat(BaseDbtUtilsBackCompat, BaseTypeFloat):
7+
pass
8+
9+
10+
# previous dbt_utils code
11+
macros__legacy_sql = """
12+
{% macro default__type_float() %}
13+
float
14+
{% endmacro %}
15+
16+
{% macro bigquery__type_float() %}
17+
float64
18+
{% endmacro %}
19+
"""
20+
21+
22+
class TestTypeFloatLegacy(BaseLegacyDataTypeMacro, BaseTypeFloat):
23+
@pytest.fixture(scope="class")
24+
def macros(self):
25+
return {
26+
"legacy.sql": macros__legacy_sql
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import pytest
2+
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
3+
from dbt.tests.adapter.utils.data_types.test_type_int import BaseTypeInt
4+
5+
6+
class TestTypeInt(BaseDbtUtilsBackCompat, BaseTypeInt):
7+
pass
8+
9+
10+
# previous dbt_utils code
11+
macros__legacy_sql = """
12+
{% macro default__type_int() %}
13+
int
14+
{% endmacro %}
15+
16+
{% macro bigquery__type_int() %}
17+
int64
18+
{% endmacro %}
19+
"""
20+
21+
22+
class TestTypeFloatLegacy(BaseLegacyDataTypeMacro, BaseTypeInt):
23+
@pytest.fixture(scope="class")
24+
def macros(self):
25+
return {
26+
"legacy.sql": macros__legacy_sql
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pytest
2+
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
3+
from dbt.tests.adapter.utils.data_types.test_type_numeric import BaseTypeNumeric
4+
5+
6+
@pytest.mark.skip_profile('bigquery')
7+
class TestTypeNumeric(BaseDbtUtilsBackCompat, BaseTypeNumeric):
8+
pass
9+
10+
11+
@pytest.mark.only_profile('bigquery')
12+
class TestBigQueryTypeNumeric(BaseDbtUtilsBackCompat, BaseTypeNumeric):
13+
def numeric_fixture_type(self):
14+
return "numeric"
15+
16+
17+
# previous dbt_utils code
18+
macros__legacy_sql = """
19+
{% macro default__type_numeric() %}
20+
numeric(28, 6)
21+
{% endmacro %}
22+
{% macro bigquery__type_numeric() %}
23+
numeric
24+
{% endmacro %}
25+
"""
26+
27+
28+
class BaseTypeNumericLegacy(BaseLegacyDataTypeMacro, BaseTypeNumeric):
29+
@pytest.fixture(scope="class")
30+
def macros(self):
31+
return {
32+
"legacy.sql": macros__legacy_sql
33+
}
34+
35+
36+
@pytest.mark.skip_profile('bigquery')
37+
class TestTypeNumeric(BaseTypeNumeric):
38+
pass
39+
40+
41+
@pytest.mark.skip_profile('bigquery')
42+
class TestTypeNumericLegacy(BaseTypeNumericLegacy):
43+
pass
44+
45+
46+
@pytest.mark.only_profile('bigquery')
47+
class TestBigQueryTypeNumericLegacy(BaseTypeNumericLegacy):
48+
def numeric_fixture_type(self):
49+
return "numeric"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import pytest
2+
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
3+
from dbt.tests.adapter.utils.data_types.test_type_string import BaseTypeString
4+
5+
6+
class TestTypeInt(BaseDbtUtilsBackCompat, BaseTypeString):
7+
pass
8+
9+
10+
# previous dbt_utils code
11+
macros__legacy_sql = """
12+
{% macro default__type_string() %}
13+
string
14+
{% endmacro %}
15+
16+
{%- macro redshift__type_string() -%}
17+
varchar
18+
{%- endmacro -%}
19+
20+
{% macro postgres__type_string() %}
21+
varchar
22+
{% endmacro %}
23+
24+
{% macro snowflake__type_string() %}
25+
varchar
26+
{% endmacro %}
27+
"""
28+
29+
30+
class TestTypeStringLegacy(BaseLegacyDataTypeMacro, BaseTypeString):
31+
@pytest.fixture(scope="class")
32+
def macros(self):
33+
return {
34+
"legacy.sql": macros__legacy_sql
35+
}

0 commit comments

Comments
 (0)