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

Use built-in adapter functionality for datatypes #586

Merged
merged 12 commits into from
Jul 5, 2022
10 changes: 4 additions & 6 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
pytest
pytest-dotenv
git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-core&subdirectory=core
git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-tests-adapter&subdirectory=tests/adapter
git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-postgres&subdirectory=plugins/postgres
git+https://github.com/dbt-labs/dbt-redshift.git
git+https://github.com/dbt-labs/dbt-snowflake.git
git+https://github.com/dbt-labs/dbt-bigquery.git
git+https://github.com/dbt-labs/dbt-core.git@jerco/data-type-macros#egg=dbt-core&subdirectory=core
git+https://github.com/dbt-labs/dbt-core.git@jerco/data-type-macros#egg=dbt-tests-adapter&subdirectory=tests/adapter
git+https://github.com/dbt-labs/dbt-bigquery.git@jerco/data-type-macros
Copy link
Contributor Author

@jtcohen6 jtcohen6 Jun 30, 2022

Choose a reason for hiding this comment

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

Now that the dbt-core PR is merged, only the dbt-bigquery PR (dbt-labs/dbt-bigquery#214) is actually blocking this one, since the Redshift + Snowflake PRs don't have substantive changes (just inheriting tests).

TODO: Add back imports from main. There was no reason to remove these.

git+https://github.com/dbt-labs/dbt-redshift.git
git+https://github.com/dbt-labs/dbt-snowflake.git

Copy link
Contributor

Choose a reason for hiding this comment

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

@jtcohen6 Just pushed these in a commit and CI is running now.

Also added back this one along with dbt-redshift and dbt-snowflake:

  • git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-postgres&subdirectory=plugins/postgres

Please let me know if I shouldn't have added that one in -- obviously easy to pull it back out.

pytest-xdist
62 changes: 15 additions & 47 deletions macros/cross_db_utils/datatypes.sql
Original file line number Diff line number Diff line change
@@ -1,99 +1,67 @@
{# These macros have been moved into dbt-core #}
{# Here for backwards compatibility ONLY #}

{# string ------------------------------------------------- #}

{%- macro type_string() -%}
{{ return(adapter.dispatch('type_string', 'dbt_utils')()) }}
{{ return(adapter.dispatch('type_string', 'dbt_utils')()) }}
{%- endmacro -%}

{% macro default__type_string() %}
string
{{ return(adapter.dispatch('type_string', 'dbt')()) }}
{% endmacro %}

{%- macro redshift__type_string() -%}
varchar
{%- endmacro -%}

{% macro postgres__type_string() %}
varchar
{% endmacro %}

{% macro snowflake__type_string() %}
varchar
{% endmacro %}



{# timestamp ------------------------------------------------- #}

{%- macro type_timestamp() -%}
{{ return(adapter.dispatch('type_timestamp', 'dbt_utils')()) }}
{{ return(adapter.dispatch('type_timestamp', 'dbt_utils')()) }}
{%- endmacro -%}

{% macro default__type_timestamp() %}
timestamp
{% endmacro %}

{% macro postgres__type_timestamp() %}
timestamp without time zone
{% endmacro %}

{% macro snowflake__type_timestamp() %}
timestamp_ntz
{{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}
{% endmacro %}


{# float ------------------------------------------------- #}

{%- macro type_float() -%}
{{ return(adapter.dispatch('type_float', 'dbt_utils')()) }}
{{ return(adapter.dispatch('type_float', 'dbt_utils')()) }}
{%- endmacro -%}

{% macro default__type_float() %}
float
{{ return(adapter.dispatch('type_float', 'dbt')()) }}
{% endmacro %}

{% macro bigquery__type_float() %}
float64
{% endmacro %}

{# numeric ------------------------------------------------ #}

{%- macro type_numeric() -%}
{{ return(adapter.dispatch('type_numeric', 'dbt_utils')()) }}
{{ return(adapter.dispatch('type_numeric', 'dbt_utils')()) }}
{%- endmacro -%}

{% macro default__type_numeric() %}
numeric(28, 6)
{% endmacro %}

{% macro bigquery__type_numeric() %}
numeric
{{ return(adapter.dispatch('type_numeric', 'dbt')()) }}
{% endmacro %}


{# bigint ------------------------------------------------- #}

{%- macro type_bigint() -%}
{{ return(adapter.dispatch('type_bigint', 'dbt_utils')()) }}
{{ return(adapter.dispatch('type_bigint', 'dbt_utils')()) }}
{%- endmacro -%}

{% macro default__type_bigint() %}
bigint
{{ return(adapter.dispatch('type_bigint', 'dbt')()) }}
{% endmacro %}

{% macro bigquery__type_bigint() %}
int64
{% endmacro %}

{# int ------------------------------------------------- #}

{%- macro type_int() -%}
{{ return(adapter.dispatch('type_int', 'dbt_utils')()) }}
{{ return(adapter.dispatch('type_int', 'dbt_utils')()) }}
{%- endmacro -%}

{% macro default__type_int() %}
int
{% endmacro %}

{% macro bigquery__type_int() %}
int64
{{ return(adapter.dispatch('type_int', 'dbt')()) }}
{% endmacro %}
2 changes: 1 addition & 1 deletion run_functional_test.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash

python3 -m pytest tests/functional --profile $1
python3 -m pytest tests/functional -n4 --profile $1
jtcohen6 marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@


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


# Using @pytest.mark.skip_adapter('apache_spark') uses the 'skip_by_adapter_type'
# Using @pytest.mark.skip_profile('postgres') uses the 'skip_by_profile_type'
# autouse fixture below
def pytest_configure(config):
config.addinivalue_line(
Expand Down
30 changes: 0 additions & 30 deletions tests/functional/cross_db_utils/base_cross_db_macro.py

This file was deleted.

6 changes: 0 additions & 6 deletions tests/functional/cross_db_utils/fixture_cross_db_macro.py

This file was deleted.

46 changes: 46 additions & 0 deletions tests/functional/data_type/base_data_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import os
import pytest
from dbt.tests.util import run_dbt, check_relations_equal, get_relation_columns
from dbt.tests.adapter.utils.data_types.base_data_type_macro import BaseDataTypeMacro

class BaseDbtUtilsBackCompat(BaseDataTypeMacro):
# install this repo as a package
@pytest.fixture(scope="class")
def packages(self):
return {"packages": [{"local": os.getcwd()}]}

# call the macros from the 'dbt_utils' namespace
# instead of the unspecified / global namespace
def macro_namespace(self):
return "dbt_utils"

# actual test sequence needs to run 'deps' first
def test_check_types_assert_match(self, project):
run_dbt(['deps'])
super().test_check_types_assert_match(project)


class BaseLegacyDataTypeMacro(BaseDbtUtilsBackCompat):
def assert_columns_equal(self, project, expected_cols, actual_cols):
# we need to be a little more lenient when mapping between 'legacy' and 'new' types that are equivalent
# e.g. 'character varying' and 'text'
if expected_cols == actual_cols:
# cool, no need for jank
pass
else:
# this is pretty janky
# our goal here: reasonable confidence that the switch from the legacy version of the dbt_utils.type_{X} macro,
# and the new version, will not constitute a breaking change for end users
for (expected_col, actual_col) in zip(expected_cols, actual_cols):
expected = project.adapter.Column(*expected_col)
actual = project.adapter.Column(*actual_col)
print(f"Subtle type difference detected: {expected.data_type} vs. {actual.data_type}")
if any((
expected.is_string() and actual.is_string(),
expected.is_float() and actual.is_float(),
expected.is_integer() and actual.is_integer(),
expected.is_numeric() and actual.is_numeric(),
)):
pytest.xfail()
else:
pytest.fail()
26 changes: 26 additions & 0 deletions tests/functional/data_type/test_type_bigint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytest
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
from dbt.tests.adapter.utils.data_types.test_type_bigint import BaseTypeBigInt


class TestTypeBigInt(BaseDbtUtilsBackCompat, BaseTypeBigInt):
pass


# previous dbt_utils code
macros__legacy_sql = """
{% macro default__type_bigint() %}
bigint
{% endmacro %}

{% macro bigquery__type_bigint() %}
int64
{% endmacro %}
"""

class TestTypeBigIntLegacy(BaseLegacyDataTypeMacro, BaseTypeBigInt):
@pytest.fixture(scope="class")
def macros(self):
return {
"legacy.sql": macros__legacy_sql
}
27 changes: 27 additions & 0 deletions tests/functional/data_type/test_type_float.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pytest
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
from dbt.tests.adapter.utils.data_types.test_type_float import BaseTypeFloat


class TestTypeFloat(BaseDbtUtilsBackCompat, BaseTypeFloat):
pass


# previous dbt_utils code
macros__legacy_sql = """
{% macro default__type_float() %}
float
{% endmacro %}

{% macro bigquery__type_float() %}
float64
{% endmacro %}
"""


class TestTypeFloatLegacy(BaseLegacyDataTypeMacro, BaseTypeFloat):
@pytest.fixture(scope="class")
def macros(self):
return {
"legacy.sql": macros__legacy_sql
}
27 changes: 27 additions & 0 deletions tests/functional/data_type/test_type_int.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pytest
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
from dbt.tests.adapter.utils.data_types.test_type_int import BaseTypeInt


class TestTypeInt(BaseDbtUtilsBackCompat, BaseTypeInt):
pass


# previous dbt_utils code
macros__legacy_sql = """
{% macro default__type_int() %}
int
{% endmacro %}

{% macro bigquery__type_int() %}
int64
{% endmacro %}
"""


class TestTypeFloatLegacy(BaseLegacyDataTypeMacro, BaseTypeInt):
@pytest.fixture(scope="class")
def macros(self):
return {
"legacy.sql": macros__legacy_sql
}
49 changes: 49 additions & 0 deletions tests/functional/data_type/test_type_numeric.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import pytest
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
from dbt.tests.adapter.utils.data_types.test_type_numeric import BaseTypeNumeric


@pytest.mark.skip_profile('bigquery')
class TestTypeNumeric(BaseDbtUtilsBackCompat, BaseTypeNumeric):
pass


@pytest.mark.only_profile('bigquery')
class TestBigQueryTypeNumeric(BaseDbtUtilsBackCompat, BaseTypeNumeric):
def numeric_fixture_type(self):
return "numeric"


# previous dbt_utils code
macros__legacy_sql = """
{% macro default__type_numeric() %}
numeric(28, 6)
{% endmacro %}
{% macro bigquery__type_numeric() %}
numeric
{% endmacro %}
"""


class BaseTypeNumericLegacy(BaseLegacyDataTypeMacro, BaseTypeNumeric):
@pytest.fixture(scope="class")
def macros(self):
return {
"legacy.sql": macros__legacy_sql
}


@pytest.mark.skip_profile('bigquery')
class TestTypeNumeric(BaseTypeNumeric):
pass


@pytest.mark.skip_profile('bigquery')
class TestTypeNumericLegacy(BaseTypeNumericLegacy):
pass


@pytest.mark.only_profile('bigquery')
class TestBigQueryTypeNumericLegacy(BaseTypeNumericLegacy):
def numeric_fixture_type(self):
return "numeric"
35 changes: 35 additions & 0 deletions tests/functional/data_type/test_type_string.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import pytest
from tests.functional.data_type.base_data_type import BaseDbtUtilsBackCompat, BaseLegacyDataTypeMacro
from dbt.tests.adapter.utils.data_types.test_type_string import BaseTypeString


class TestTypeInt(BaseDbtUtilsBackCompat, BaseTypeString):
pass


# previous dbt_utils code
macros__legacy_sql = """
{% macro default__type_string() %}
string
{% endmacro %}

{%- macro redshift__type_string() -%}
varchar
{%- endmacro -%}

{% macro postgres__type_string() %}
varchar
{% endmacro %}

{% macro snowflake__type_string() %}
varchar
{% endmacro %}
"""


class TestTypeStringLegacy(BaseLegacyDataTypeMacro, BaseTypeString):
@pytest.fixture(scope="class")
def macros(self):
return {
"legacy.sql": macros__legacy_sql
}
Loading