Skip to content

Commit b434592

Browse files
authored
Merge branch 'dbt-msft:master' into column-nvarchar-dtype
2 parents 05156f7 + bcf4ac9 commit b434592

File tree

14 files changed

+146
-20
lines changed

14 files changed

+146
-20
lines changed

.github/workflows/integration-tests-sqlserver.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
name: Regular
1919
strategy:
2020
matrix:
21-
python_version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
21+
python_version: ["3.9", "3.10", "3.11", "3.12"]
2222
msodbc_version: ["17", "18"]
2323
sqlserver_version: ["2017", "2019", "2022"]
2424
collation: ["SQL_Latin1_General_CP1_CS_AS", "SQL_Latin1_General_CP1_CI_AS"]

.github/workflows/publish-docker.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
publish-docker-client:
1313
strategy:
1414
matrix:
15-
python_version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
15+
python_version: ["3.9", "3.10", "3.11", "3.12"]
1616
docker_target: ["msodbc17", "msodbc18"]
1717
runs-on: ubuntu-latest
1818
permissions:

.github/workflows/unit-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
name: Unit tests
1919
strategy:
2020
matrix:
21-
python_version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
21+
python_version: ["3.9", "3.10", "3.11", "3.12"]
2222
runs-on: ubuntu-latest
2323
permissions:
2424
contents: read

dbt/adapters/sqlserver/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = "1.8.7"
1+
version = "1.9.0"

dbt/adapters/sqlserver/sqlserver_adapter.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,9 @@ def render_model_constraint(cls, constraint) -> Optional[str]:
5959
@classmethod
6060
def date_function(cls):
6161
return "getdate()"
62+
63+
def valid_incremental_strategies(self):
64+
"""The set of standard builtin strategies which this adapter supports out-of-the-box.
65+
Not used to validate custom strategies defined by end users.
66+
"""
67+
return ["append", "delete+insert", "merge", "microbatch"]

dbt/adapters/sqlserver/sqlserver_relation.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from dataclasses import dataclass, field
22
from typing import Optional, Type
33

4-
from dbt.adapters.base.relation import BaseRelation
4+
from dbt.adapters.base.relation import BaseRelation, EventTimeFilter
55
from dbt.adapters.utils import classproperty
66
from dbt_common.exceptions import DbtRuntimeError
77

@@ -49,3 +49,28 @@ def __post_init__(self):
4949

5050
def relation_max_name_length(self):
5151
return MAX_CHARACTERS_IN_IDENTIFIER
52+
53+
def _render_event_time_filtered(self, event_time_filter: EventTimeFilter) -> str:
54+
"""
55+
Returns "" if start and end are both None
56+
"""
57+
filter = ""
58+
if event_time_filter.start and event_time_filter.end:
59+
filter = (
60+
f"{event_time_filter.field_name} >="
61+
f" cast('{event_time_filter.start}' as datetimeoffset)"
62+
f" and {event_time_filter.field_name} <"
63+
f" cast('{event_time_filter.end}' as datetimeoffset)"
64+
)
65+
elif event_time_filter.start:
66+
filter = (
67+
f"{event_time_filter.field_name} >="
68+
f" cast('{event_time_filter.start}' as datetimeoffset)"
69+
)
70+
elif event_time_filter.end:
71+
filter = (
72+
f"{event_time_filter.field_name} <"
73+
f" cast('{event_time_filter.end}' as datetimeoffset)"
74+
)
75+
76+
return filter

dbt/include/sqlserver/dbt_project.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: dbt_sqlserver
2-
version: 1.8.0
2+
version: 1.9.0
33
config-version: 2
44

55
macro-paths: ["macros"]

dbt/include/sqlserver/macros/adapter/columns.sql

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
{% macro sqlserver__get_empty_subquery_sql(select_sql, select_sql_header=none) %}
2+
{% if select_sql.strip().lower().startswith('with') %}
3+
{{ select_sql }}
4+
{% else -%}
5+
select * from (
6+
{{ select_sql }}
7+
) dbt_sbq_tmp
8+
where 1 = 0
9+
{%- endif -%}
10+
11+
{% endmacro %}
12+
13+
{% macro sqlserver__get_columns_in_query(select_sql) %}
14+
{% set query_label = apply_label() %}
15+
{% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}
16+
select TOP 0 * from (
17+
{{ select_sql }}
18+
) as __dbt_sbq
19+
where 0 = 1
20+
{{ query_label }}
21+
{% endcall %}
22+
23+
{{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}
24+
{% endmacro %}
25+
126
{% macro sqlserver__alter_column_type(relation, column_name, new_column_type) %}
227

328
{%- set tmp_column = column_name + "__dbt_alter" -%}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{% macro sqlserver__get_incremental_microbatch_sql(arg_dict) %}
2+
{%- set target = arg_dict["target_relation"] -%}
3+
{%- set source = arg_dict["temp_relation"] -%}
4+
{%- set dest_columns = arg_dict["dest_columns"] -%}
5+
{%- set incremental_predicates = [] if arg_dict.get('incremental_predicates') is none else arg_dict.get('incremental_predicates') -%}
6+
7+
{#-- Add additional incremental_predicates to filter for batch --#}
8+
{% if model.config.get("__dbt_internal_microbatch_event_time_start") -%}
9+
{{ log("incremental append event start time > DBT_INTERNAL_TARGET." ~ model.config.event_time ~ " >= cast('" ~ model.config.__dbt_internal_microbatch_event_time_start ~ "' as datetimeoffset)") }}
10+
{% do incremental_predicates.append("DBT_INTERNAL_TARGET." ~ model.config.event_time ~ " >= cast('" ~ model.config.__dbt_internal_microbatch_event_time_start ~ "' as datetimeoffset)") %}
11+
{% endif %}
12+
{% if model.config.__dbt_internal_microbatch_event_time_end -%}
13+
{{ log("incremental append event end time < DBT_INTERNAL_TARGET." ~ model.config.event_time ~ " < cast('" ~ model.config.__dbt_internal_microbatch_event_time_end ~ "' as datetimeoffset)") }}
14+
{% do incremental_predicates.append("DBT_INTERNAL_TARGET." ~ model.config.event_time ~ " < cast('" ~ model.config.__dbt_internal_microbatch_event_time_end ~ "' as datetimeoffset)") %}
15+
{% endif %}
16+
{% do arg_dict.update({'incremental_predicates': incremental_predicates}) %}
17+
18+
delete DBT_INTERNAL_TARGET from {{ target }} AS DBT_INTERNAL_TARGET
19+
where (
20+
{% for predicate in incremental_predicates %}
21+
{%- if not loop.first %}and {% endif -%} {{ predicate }}
22+
{% endfor %}
23+
);
24+
25+
{%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute="name")) -%}
26+
insert into {{ target }} ({{ dest_cols_csv }})
27+
(
28+
select {{ dest_cols_csv }}
29+
from {{ source }}
30+
)
31+
{% endmacro %}

dev_requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
dbt-tests-adapter>=1.8.0, <1.9.0
2+
dbt-tests-adapter>=1.9.0,<2.0
33

44
ruff
55
black==24.8.0

setup.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
package_name = "dbt-sqlserver"
1010
authors_list = ["Mikael Ene", "Anders Swanson", "Sam Debruyn", "Cor Zuurmond", "Cody Scott"]
11-
dbt_version = "1.8"
11+
dbt_version = "1.9"
1212
description = """A Microsoft SQL Server adapter plugin for dbt"""
1313

1414
this_directory = os.path.abspath(os.path.dirname(__file__))
@@ -66,10 +66,10 @@ def run(self):
6666
packages=find_namespace_packages(include=["dbt", "dbt.*"]),
6767
include_package_data=True,
6868
install_requires=[
69-
"dbt-fabric>=1.8.0,<1.9.0",
70-
"dbt-core>=1.8.0,<1.9.0",
69+
"dbt-fabric==1.9.3",
70+
"dbt-core>=1.9.0,<2.0",
7171
"dbt-common>=1.0,<2.0",
72-
"dbt-adapters>=1.1.1,<2.0",
72+
"dbt-adapters>=1.11.0,<2.0",
7373
],
7474
cmdclass={
7575
"verify": VerifyVersionCommand,

tests/functional/adapter/dbt/test_empty.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import pytest
2+
from dbt.tests.adapter.empty._models import model_input_sql, schema_sources_yml
23

34
# switch for 1.9
45
# from dbt.tests.adapter.empty import _models
56
from dbt.tests.adapter.empty.test_empty import ( # MetadataWithEmptyFlag
67
BaseTestEmpty,
78
BaseTestEmptyInlineSourceRef,
8-
model_input_sql,
9-
schema_sources_yml,
109
)
1110
from dbt.tests.util import run_dbt
1211

tests/functional/adapter/dbt/test_incremental.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import pytest
22
from dbt.tests.adapter.incremental import fixtures
3-
from dbt.tests.adapter.incremental.test_incremental_merge_exclude_columns import (
4-
BaseMergeExcludeColumns,
5-
)
63
from dbt.tests.adapter.incremental.test_incremental_on_schema_change import (
74
BaseIncrementalOnSchemaChange,
85
)
@@ -76,10 +73,6 @@
7673
"""
7774

7875

79-
class TestIncrementalMergeExcludeColumns(BaseMergeExcludeColumns):
80-
pass
81-
82-
8376
class TestIncrementalOnSchemaChange(BaseIncrementalOnSchemaChange):
8477
@pytest.fixture(scope="class")
8578
def models(self):
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import pytest
2+
from dbt.tests.adapter.incremental.test_incremental_microbatch import BaseMicrobatch
3+
4+
_microbatch_model_no_unique_id_sql_datetime = """
5+
{{ config(materialized='incremental', incremental_strategy='microbatch',
6+
event_time='event_time', batch_size='day', begin='2020-01-01 00:00:00') }}
7+
select * from {{ ref('input_model') }}
8+
"""
9+
10+
_input_model_sql_datetime = """
11+
{{ config(materialized='table', event_time='event_time') }}
12+
select 1 as id, '2020-01-01 00:00:00' as event_time
13+
union all
14+
select 2 as id, '2020-01-02 00:00:00' as event_time
15+
union all
16+
select 3 as id, '2020-01-03 00:00:00' as event_time
17+
"""
18+
19+
20+
class TestSQLServerMicrobatchDateTime(BaseMicrobatch):
21+
"""
22+
Setup a version of the microbatch testing that uses a datetime column as the event_time
23+
This is to test that the microbatch strategy can handle datetime columns when passing in
24+
event times as UTC strings
25+
"""
26+
27+
@pytest.fixture(scope="class")
28+
def microbatch_model_sql(self) -> str:
29+
return _microbatch_model_no_unique_id_sql_datetime
30+
31+
@pytest.fixture(scope="class")
32+
def input_model_sql(self) -> str:
33+
"""
34+
This is the SQL that defines the input model to the microbatch model,
35+
including any {{ config(..) }}. event_time is a required configuration of this input
36+
"""
37+
return _input_model_sql_datetime
38+
39+
@pytest.fixture(scope="class")
40+
def insert_two_rows_sql(self, project) -> str:
41+
test_schema_relation = project.adapter.Relation.create(
42+
database=project.database, schema=project.test_schema
43+
)
44+
return (
45+
f"insert into {test_schema_relation}.input_model (id, event_time) "
46+
f"values (4, '2020-01-04 00:00:00'), (5, '2020-01-05 00:00:00')"
47+
)

0 commit comments

Comments
 (0)