Skip to content

Commit e8a59ed

Browse files
authored
Merge pull request #111 from microsoft/v1.7.3
releasing v1.7.3
2 parents 458f821 + 8cda499 commit e8a59ed

13 files changed

Lines changed: 233 additions & 15 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
### v1.7.3
4+
5+
## Enhancements
6+
7+
* Overwritten view adapter materialization and made improvements.
8+
* Overwritten table adapter materizalization and made improvements in handling model level constraints
9+
* Made Constraint name mandatory
10+
* Added several macros to manage indexes, dropping table dependencies and managing model level constraints
11+
* Bump dbt-tests-adapter requirement from ~=1.7.3 to ~=1.7.4
12+
* Bump py-test adapter requirement from ~=pytest==7.4.3 to ~=pytest==7.4.4
13+
* Bump precommit adapter requirement from ~=pre-commit==3.5.0 to ~=pre-commit==3.6.0
14+
315
### v1.7.2
416

517
## Bug Fixes

dbt/adapters/fabric/__version__.py

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

dbt/adapters/fabric/fabric_adapter.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import List, Optional
22

33
import agate
4+
import dbt.exceptions
45
from dbt.adapters.base import Column as BaseColumn
56

67
# from dbt.events.functions import fire_event
@@ -202,6 +203,13 @@ def render_model_constraint(cls, constraint: ModelLevelConstraint) -> Optional[s
202203
constraint_prefix = "add constraint "
203204
column_list = ", ".join(constraint.columns)
204205

206+
if constraint.name is None:
207+
raise dbt.exceptions.DbtDatabaseError(
208+
"Constraint name cannot be empty. Provide constraint name - column "
209+
+ column_list
210+
+ " and run the project again."
211+
)
212+
205213
if constraint.type == ConstraintType.unique:
206214
return (
207215
constraint_prefix

dbt/include/fabric/macros/adapters/indexes.sql

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,36 @@
1818
{# {% exceptions.raise_compiler_error('Indexes are not supported') %} #}
1919
{% endmacro %}
2020

21-
{% macro drop_all_indexes_on_table() -%}
22-
{# {% exceptions.raise_compiler_error('Indexes are not supported') %} #}
21+
{% macro drop_fk_indexes_on_table(relation) -%}
22+
{% call statement('find_references', fetch_result=true) %}
23+
USE [{{ relation.database }}];
24+
SELECT obj.name AS FK_NAME,
25+
sch.name AS [schema_name],
26+
tab1.name AS [table],
27+
col1.name AS [column],
28+
tab2.name AS [referenced_table],
29+
col2.name AS [referenced_column]
30+
FROM sys.foreign_key_columns fkc
31+
INNER JOIN sys.objects obj
32+
ON obj.object_id = fkc.constraint_object_id
33+
INNER JOIN sys.tables tab1
34+
ON tab1.object_id = fkc.parent_object_id
35+
INNER JOIN sys.schemas sch
36+
ON tab1.schema_id = sch.schema_id
37+
INNER JOIN sys.columns col1
38+
ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
39+
INNER JOIN sys.tables tab2
40+
ON tab2.object_id = fkc.referenced_object_id
41+
INNER JOIN sys.columns col2
42+
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
43+
WHERE sch.name = '{{ relation.schema }}' and tab2.name = '{{ relation.identifier }}'
44+
{% endcall %}
45+
{% set references = load_result('find_references')['data'] %}
46+
{% for reference in references -%}
47+
{% call statement('main') -%}
48+
alter table [{{reference[1]}}].[{{reference[2]}}] drop constraint [{{reference[0]}}]
49+
{%- endcall %}
50+
{% endfor %}
2351
{% endmacro %}
2452

2553
{% macro create_clustered_index(columns, unique=False) -%}
@@ -29,3 +57,38 @@
2957
{% macro create_nonclustered_index(columns, includes=False) %}
3058
{# {% exceptions.raise_compiler_error('Indexes are not supported') %} #}
3159
{% endmacro %}
60+
61+
{% macro fabric__list_nonclustered_rowstore_indexes(relation) -%}
62+
{% call statement('list_nonclustered_rowstore_indexes', fetch_result=True) -%}
63+
64+
SELECT i.name AS index_name
65+
, i.name + '__dbt_backup' as index_new_name
66+
, COL_NAME(ic.object_id,ic.column_id) AS column_name
67+
FROM sys.indexes AS i
68+
INNER JOIN sys.index_columns AS ic
69+
ON i.object_id = ic.object_id AND i.index_id = ic.index_id and i.type <> 5
70+
WHERE i.object_id = OBJECT_ID('{{ relation.schema }}.{{ relation.identifier }}')
71+
72+
UNION ALL
73+
74+
SELECT obj.name AS index_name
75+
, obj.name + '__dbt_backup' as index_new_name
76+
, col1.name AS column_name
77+
FROM sys.foreign_key_columns fkc
78+
INNER JOIN sys.objects obj
79+
ON obj.object_id = fkc.constraint_object_id
80+
INNER JOIN sys.tables tab1
81+
ON tab1.object_id = fkc.parent_object_id
82+
INNER JOIN sys.schemas sch
83+
ON tab1.schema_id = sch.schema_id
84+
INNER JOIN sys.columns col1
85+
ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
86+
INNER JOIN sys.tables tab2
87+
ON tab2.object_id = fkc.referenced_object_id
88+
INNER JOIN sys.columns col2
89+
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
90+
WHERE sch.name = '{{ relation.schema }}' and tab1.name = '{{ relation.identifier }}'
91+
92+
{% endcall %}
93+
{{ return(load_result('list_nonclustered_rowstore_indexes').table) }}
94+
{% endmacro %}

dbt/include/fabric/macros/adapters/metadata.sql

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
{% endmacro %}
2828

2929
{% macro fabric__list_relations_without_caching(schema_relation) -%}
30-
{{ log("schema_relation in fabric__list_relations_without_caching is " ~ schema_relation.schema, info=True) }}
3130
{% call statement('list_relations_without_caching', fetch_result=True) -%}
3231
select
3332
table_catalog as [database],
@@ -44,8 +43,25 @@
4443
{{ return(load_result('list_relations_without_caching').table) }}
4544
{% endmacro %}
4645

46+
{% macro fabric__get_relation_without_caching(schema_relation) -%}
47+
{% call statement('list_relations_without_caching', fetch_result=True) -%}
48+
select
49+
table_catalog as [database],
50+
table_name as [name],
51+
table_schema as [schema],
52+
case when table_type = 'BASE TABLE' then 'table'
53+
when table_type = 'VIEW' then 'view'
54+
else table_type
55+
end as table_type
56+
57+
from INFORMATION_SCHEMA.TABLES {{ information_schema_hints() }}
58+
where table_schema like '{{ schema_relation.schema }}'
59+
and table_name like '{{ schema_relation.identifier }}'
60+
{% endcall %}
61+
{{ return(load_result('list_relations_without_caching').table) }}
62+
{% endmacro %}
63+
4764
{% macro fabric__get_relation_last_modified(information_schema, relations) -%}
48-
{{ log("information_schema - "~ information_schema, info=True) }}
4965
{%- call statement('last_modified', fetch_result=True) -%}
5066
select
5167
o.name as [identifier]

dbt/include/fabric/macros/adapters/relation.sql

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,38 @@
3939
path={"schema": reference[0], "identifier": reference[1]})) }}
4040
{% endfor %}
4141
{% elif relation.type == 'table'%}
42+
{# {% call statement('find_references', fetch_result=true) %}
43+
USE [{{ relation.database }}];
44+
SELECT obj.name AS FK_NAME,
45+
sch.name AS [schema_name],
46+
tab1.name AS [table],
47+
col1.name AS [column],
48+
tab2.name AS [referenced_table],
49+
col2.name AS [referenced_column]
50+
FROM sys.foreign_key_columns fkc
51+
INNER JOIN sys.objects obj
52+
ON obj.object_id = fkc.constraint_object_id
53+
INNER JOIN sys.tables tab1
54+
ON tab1.object_id = fkc.parent_object_id
55+
INNER JOIN sys.schemas sch
56+
ON tab1.schema_id = sch.schema_id
57+
INNER JOIN sys.columns col1
58+
ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
59+
INNER JOIN sys.tables tab2
60+
ON tab2.object_id = fkc.referenced_object_id
61+
INNER JOIN sys.columns col2
62+
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
63+
WHERE sch.name = '{{ relation.schema }}' and tab2.name = '{{ relation.identifier }}'
64+
{% endcall %}
65+
{% set references = load_result('find_references')['data'] %}
66+
{% for reference in references -%}
67+
-- dropping referenced table {{ reference[0] }}.{{ reference[1] }}
68+
{{ fabric__drop_relation_script(relation.incorporate(
69+
type="table",
70+
path={"schema": reference[1], "identifier": reference[2]})) }}
71+
{% endfor %} #}
4272
{% set object_id_type = 'U' %}
73+
4374
{%- else -%}
4475
{{ exceptions.raise_not_implemented('Invalid relation being dropped: ' ~ relation) }}
4576
{% endif %}
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
{% macro fabric__table_columns_and_constraints(relation) %}
1+
{% macro fabric__build_columns_constraints(relation) %}
22
{# loop through user_provided_columns to create DDL with data types and constraints #}
33
{%- set raw_column_constraints = adapter.render_raw_columns_constraints(raw_columns=model['columns']) -%}
4-
{%- set raw_model_constraints = adapter.render_raw_model_constraints(raw_constraints=model['constraints']) -%}
54
(
65
{% for c in raw_column_constraints -%}
76
{{ c }}{{ "," if not loop.last }}
87
{% endfor %}
98
)
9+
{% endmacro %}
10+
11+
{% macro fabric__build_model_constraints(relation) %}
12+
{# loop through user_provided_columns to create DDL with data types and constraints #}
13+
{%- set raw_model_constraints = adapter.render_raw_model_constraints(raw_constraints=model['constraints']) -%}
1014
{% for c in raw_model_constraints -%}
1115
{% set alter_table_script %}
1216
alter table {{ relation.include(database=False) }} {{c}};
1317
{%endset%}
14-
EXEC('{{alter_table_script}};')
18+
{% call statement('alter_table_add_constraint') -%}
19+
{{alter_table_script}}
20+
{%- endcall %}
1521
{% endfor -%}
1622
{% endmacro %}

dbt/include/fabric/macros/materializations/models/table/create_table_as.sql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44
path={"identifier": relation.identifier.replace("#", "") ~ '_temp_view'},
55
type='view')-%}
66
{% do run_query(fabric__drop_relation_script(tmp_relation)) %}
7-
{% do run_query(fabric__drop_relation_script(relation)) %}
87

98
{% set contract_config = config.get('contract') %}
109

1110
{{ fabric__create_view_as(tmp_relation, sql) }}
1211
{% if contract_config.enforced %}
1312

1413
CREATE TABLE [{{relation.database}}].[{{relation.schema}}].[{{relation.identifier}}]
15-
{{ fabric__table_columns_and_constraints(relation) }}
14+
{{ fabric__build_columns_constraints(relation) }}
1615
{{ get_assert_columns_equivalent(sql) }}
1716

1817
{% set listColumns %}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{% materialization table, adapter='fabric' %}
2+
3+
-- Create target relation
4+
{%- set target_relation = this.incorporate(type='table') %}
5+
-- grab current tables grants config for comparision later on
6+
{% set grant_config = config.get('grants') %}
7+
{%- set backup_relation = make_backup_relation(target_relation, 'table') -%}
8+
-- drop the temp relations if they exist already in the database
9+
{{ drop_relation_if_exists(backup_relation) }}
10+
-- Rename target relation as backup relation
11+
{%- set relation = fabric__get_relation_without_caching(target_relation) %}
12+
{% if relation|length > 0 %}
13+
{{ adapter.rename_relation(target_relation, backup_relation) }}
14+
{% endif %}
15+
16+
{{ run_hooks(pre_hooks, inside_transaction=False) }}
17+
-- `BEGIN` happens here:
18+
{{ run_hooks(pre_hooks, inside_transaction=True) }}
19+
20+
-- build model
21+
{% call statement('main') -%}
22+
{{ get_create_table_as_sql(False, target_relation, sql) }}
23+
{%- endcall %}
24+
25+
-- cleanup
26+
{{ run_hooks(post_hooks, inside_transaction=True) }}
27+
{% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}
28+
{% do persist_docs(target_relation, model) %}
29+
-- `COMMIT` happens here
30+
{{ adapter.commit() }}
31+
32+
-- finally, drop the foreign key references if exists
33+
{{ drop_fk_indexes_on_table(backup_relation) }}
34+
-- drop existing/backup relation after the commit
35+
{{ drop_relation_if_exists(backup_relation) }}
36+
-- Add constraints including FK relation.
37+
{{ fabric__build_model_constraints(target_relation) }}
38+
{{ run_hooks(post_hooks, inside_transaction=False) }}
39+
{{ return({'relations': [target_relation]}) }}
40+
41+
{% endmaterialization %}

dbt/include/fabric/macros/materializations/models/view/create_view_as.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
{% macro fabric__create_view_exec(relation, sql) -%}
66

77
{%- set temp_view_sql = sql.replace("'", "''") -%}
8+
89
USE [{{ relation.database }}];
910
{% set contract_config = config.get('contract') %}
1011
{% if contract_config.enforced %}

0 commit comments

Comments
 (0)