dbt-sqlserver 1.12.0rc4__tar.gz → 1.12.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/PKG-INFO +21 -14
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/README.md +20 -13
- dbt_sqlserver-1.12.2/dbt/adapters/sqlserver/__version__.py +1 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_adapter.py +90 -8
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_configs.py +2 -1
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/columns.sql +31 -4
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/metadata.sql +13 -4
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/relation.sql +20 -11
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/incremental/incremental.sql +2 -1
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/incremental/merge.sql +3 -3
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/view/view.sql +5 -1
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/snapshots/helpers.sql +1 -1
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/snapshots/snapshot.sql +2 -1
- dbt_sqlserver-1.12.2/dbt/include/sqlserver/macros/materializations/snapshots/strategies.sql +65 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/unit_tests.sql +10 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/relations/table/create.sql +4 -0
- dbt_sqlserver-1.12.2/dbt/include/sqlserver/macros/utils/array_append.sql +3 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt_sqlserver.egg-info/PKG-INFO +21 -14
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt_sqlserver.egg-info/SOURCES.txt +1 -0
- dbt_sqlserver-1.12.0rc4/dbt/adapters/sqlserver/__version__.py +0 -1
- dbt_sqlserver-1.12.0rc4/dbt/include/sqlserver/macros/materializations/snapshots/strategies.sql +0 -5
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/LICENSE +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/__init__.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/__init__.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/py.typed +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/relation_configs/__init__.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/relation_configs/index.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/relation_configs/policies.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_auth.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_backend.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_column.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_connections.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_constants.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_credentials.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_deny.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_helpers.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_mask.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_relation.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_runtime.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/__init__.py +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/dbt_project.yml +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/apply_denies.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/apply_grants.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/apply_masks.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/catalog.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/indexes.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/persist_docs.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/schema.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/show.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/validate_sql.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/functions/helpers.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/functions/scalar.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/hooks.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/incremental/incremental_strategies.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/table/columns_spec_ddl.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/table/table.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/table/table_dml_refresh.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/unit_test/get_fixture_sql.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/unit_test/unit_test_create_table_as.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/models/view/create_view_as.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/snapshots/snapshot_merge.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/materializations/tests.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/relations/seeds/helpers.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/relations/table/clone.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/relations/views/create.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/any_value.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/array_construct.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/cast_bool_to_text.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/concat.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/date_trunc.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/dateadd.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/get_tables_by_pattern.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/hash.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/last_day.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/length.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/listagg.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/openquery.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/position.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/safe_cast.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/split_part.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/timestamps.sql +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/profile_template.yml +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt_sqlserver.egg-info/dependency_links.txt +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt_sqlserver.egg-info/requires.txt +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt_sqlserver.egg-info/top_level.txt +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/pyproject.toml +0 -0
- {dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbt-sqlserver
|
|
3
|
-
Version: 1.12.
|
|
3
|
+
Version: 1.12.2
|
|
4
4
|
Summary: A Microsoft SQL Server adapter plugin for dbt
|
|
5
5
|
Author: Mikael Ene, Anders Swanson, Sam Debruyn, Cor Zuurmond, Cody Scott
|
|
6
6
|
License: MIT
|
|
@@ -77,7 +77,7 @@ We've bundled all documentation on the dbt docs site:
|
|
|
77
77
|
- [Profile setup & authentication](https://docs.getdbt.com/reference/warehouse-profiles/mssql-profile)
|
|
78
78
|
- [Adapter documentation, usage and important notes](https://docs.getdbt.com/reference/resource-configs/mssql-configs)
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
Ask questions and get help in [GitHub Discussions](https://github.com/dbt-msft/dbt-sqlserver/discussions/categories/q-a). The [dbt Slack](https://getdbt.slack.com/archives/CMRMDDQ9W) channel is there for chatting with the community.
|
|
81
81
|
|
|
82
82
|
## Installation
|
|
83
83
|
|
|
@@ -166,11 +166,11 @@ An Arrow-native backend built on [ADBC](https://arrow.apache.org/adbc/), avoidin
|
|
|
166
166
|
pip install -U "dbt-sqlserver[adbc]"
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
The driver binary is not on PyPI and must be installed once via the `dbc` CLI. See [docs/adbc_backend.md](docs/adbc_backend.md) for the full setup, configuration, and known-differences guide.
|
|
169
|
+
The driver binary is not on PyPI and must be installed once via the `dbc` CLI. See [docs/adbc_backend.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/adbc_backend.md) for the full setup, configuration, and known-differences guide.
|
|
170
170
|
|
|
171
171
|
## Changelog
|
|
172
172
|
|
|
173
|
-
See [the changelog](CHANGELOG.md)
|
|
173
|
+
See [the changelog](https://github.com/dbt-msft/dbt-sqlserver/blob/master/CHANGELOG.md)
|
|
174
174
|
|
|
175
175
|
## Configuration
|
|
176
176
|
|
|
@@ -201,7 +201,7 @@ The same setting is also honoured via `vars:` for backwards compatibility; the b
|
|
|
201
201
|
|
|
202
202
|
### `backend`
|
|
203
203
|
|
|
204
|
-
*(default: `pyodbc`)* Set to `mssql-python` or `adbc` (experimental, see [docs/adbc_backend.md](docs/adbc_backend.md)) in a profile target to use that backend instead of `pyodbc`. The adapter fails if the required backend package (Python dependency), such as `pyodbc`, `mssql-python`, or `adbc-driver-manager`, is not installed.
|
|
204
|
+
*(default: `pyodbc`)* Set to `mssql-python` or `adbc` (experimental, see [docs/adbc_backend.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/adbc_backend.md)) in a profile target to use that backend instead of `pyodbc`. The adapter fails if the required backend package (Python dependency), such as `pyodbc`, `mssql-python`, or `adbc-driver-manager`, is not installed.
|
|
205
205
|
|
|
206
206
|
### `dbt_sqlserver_enable_safe_type_expansion`
|
|
207
207
|
|
|
@@ -227,7 +227,7 @@ two paths that commit a full-refresh marker before the load
|
|
|
227
227
|
existing table), where neither scope can roll it back. `build` stages
|
|
228
228
|
it inside the hook's transaction, for the one case `load` cannot serve: a
|
|
229
229
|
`transaction: true` pre-hook that creates an object the model reads. See
|
|
230
|
-
[docs/transaction_scope.md](docs/transaction_scope.md) for the full flow and
|
|
230
|
+
[docs/transaction_scope.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/transaction_scope.md) for the full flow and
|
|
231
231
|
the post-hook ordering change.
|
|
232
232
|
|
|
233
233
|
### `dbt_sqlserver_use_dbt_transactions`
|
|
@@ -240,11 +240,12 @@ The driver connection remains in autocommit mode (`autocommit=true`) in both mod
|
|
|
240
240
|
|
|
241
241
|
This is now the default and should be tested carefully with project-specific materializations and hooks. Projects that depend on autocommit-only behavior should set the flag to `false` during migration.
|
|
242
242
|
|
|
243
|
+
**Compatibility notes:** Enabling `dbt_sqlserver_use_dbt_transactions: true` may expose transaction-state assumptions hidden by autocommit-only mode. Explicit transaction macros may interact with dbt-managed transactions, and cleanup after failed DDL/DML may differ. Review pre/post hooks for in-transaction vs out-of-transaction semantics.
|
|
244
|
+
|
|
243
245
|
```yaml
|
|
244
246
|
# dbt_project.yml
|
|
245
247
|
flags:
|
|
246
|
-
|
|
247
|
-
dbt_sqlserver_use_dbt_transactions: true # default
|
|
248
|
+
dbt_sqlserver_use_dbt_transactions: false # legacy autocommit; deprecated
|
|
248
249
|
```
|
|
249
250
|
|
|
250
251
|
### `dbt_sqlserver_use_native_string_types`
|
|
@@ -287,7 +288,11 @@ your_profile:
|
|
|
287
288
|
|
|
288
289
|
### `prefer_single_alter_column`
|
|
289
290
|
|
|
290
|
-
*(default:
|
|
291
|
+
*(default: unset)* Model-level config that controls how `alter_column_type` changes column types on tables:
|
|
292
|
+
|
|
293
|
+
* `true`: a single `ALTER COLUMN` statement. It is atomic, instant for a longer `varchar`/`nvarchar`, and keeps the column's indexes, default constraint and position. It fails for types that cannot be implicitly converted, and changing `varchar` to `nvarchar` on a large clustered columnstore table can fail with Msg 35357 (dictionary size limit).
|
|
294
|
+
* `false`: add a temporary column, copy the data, drop the original and rename. It fails when an index, default constraint or statistics object depends on the column, and it moves the column to the end of the table. A failed attempt no longer blocks the next run.
|
|
295
|
+
* unset (default): `true` when column type expansion widens a column within its type (a longer `varchar`, or `varchar(max)`), `false` for every other change.
|
|
291
296
|
|
|
292
297
|
```sql
|
|
293
298
|
-- In an incremental model
|
|
@@ -295,8 +300,6 @@ your_profile:
|
|
|
295
300
|
prefer_single_alter_column=true) }}
|
|
296
301
|
```
|
|
297
302
|
|
|
298
|
-
**Compatibility notes:** Enabling `dbt_sqlserver_use_dbt_transactions: true` may expose transaction-state assumptions hidden by autocommit-only mode. Explicit transaction macros may interact with dbt-managed transactions, and cleanup after failed DDL/DML may differ. Review pre/post hooks for in-transaction vs out-of-transaction semantics.
|
|
299
|
-
|
|
300
303
|
### `as_columnstore`
|
|
301
304
|
|
|
302
305
|
*(default: `true`)* When building a table, the adapter creates a [clustered columnstore index](https://learn.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-overview) (CCI) on it. Set `as_columnstore: false` to build a plain rowstore table instead.
|
|
@@ -322,6 +325,10 @@ You can also set it per model:
|
|
|
322
325
|
|
|
323
326
|
With `table_refresh_method: dml`, a schema change makes the refresh fall back to a rename-swap. On that run — and only that run — the scratch table is rebuilt the way this adapter builds every other table, so it carries the model's columnstore index, and under an enforced contract its `NOT NULL`s and inline constraints, into the swap. That run therefore executes the model's SQL twice — once for the `SELECT … INTO` that probes for the schema change, once for the rebuild — and builds the columnstore index once. Steady-state refreshes are unaffected and keep the single `SELECT … INTO`. A table that lost its columnstore index to this bug before you upgraded is not repaired automatically: its schema still matches, so it stays on the cheap path. To rebuild it, temporarily set `full_refresh_build: prebuilt` and run with `--full-refresh`.
|
|
324
327
|
|
|
328
|
+
### Ephemeral models
|
|
329
|
+
|
|
330
|
+
Ephemeral models are supported, with one limit: an ephemeral model can't start with its own `WITH`. dbt inlines it as a CTE, and T-SQL can't nest a `WITH` inside one (still true on SQL Server 2025). Write it with derived tables instead, or materialize it as a `view`, which SQL Server expands into the calling query the same way.
|
|
331
|
+
|
|
325
332
|
### Constraints
|
|
326
333
|
|
|
327
334
|
Constraints declared in a model's yaml are applied when — and only when — the model's [contract](https://docs.getdbt.com/reference/resource-configs/contract) is enforced, which is what every dbt adapter does and keeps their cost opt-in. (dbt-core does not raise if you declare constraints with the contract off — they are simply never emitted.) `not_null`, `check`, `unique`, `primary_key` and `foreign_key` are all supported.
|
|
@@ -334,7 +341,7 @@ A *model-level* constraint carrying `name:` is applied by `ALTER TABLE … ADD C
|
|
|
334
341
|
|
|
335
342
|
Name a constraint when you want it stable across environments (schema-comparison tools report the generated names as differences) or need to reference it later. A `name:` on a *column-level* constraint is ignored with a warning — declare it under the model's `constraints:` key instead.
|
|
336
343
|
|
|
337
|
-
The full set of rules, with the test that verifies each, is in [docs/constraints.md](docs/constraints.md).
|
|
344
|
+
The full set of rules, with the test that verifies each, is in [docs/constraints.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/constraints.md).
|
|
338
345
|
|
|
339
346
|
```yaml
|
|
340
347
|
models:
|
|
@@ -492,8 +499,8 @@ The `denies` config re-applies object-level DENYs after each build, diffed again
|
|
|
492
499
|
[](https://github.com/dbt-msft/dbt-sqlserver/actions/workflows/integration-tests-sqlserver.yml)
|
|
493
500
|
|
|
494
501
|
This adapter is community-maintained.
|
|
495
|
-
You are welcome to contribute by creating issues, opening or reviewing pull requests, or helping other users in the Slack
|
|
496
|
-
If you're unsure how to get started, check out our [contributing guide](CONTRIBUTING.md).
|
|
502
|
+
You are welcome to contribute by creating issues, opening or reviewing pull requests, or helping other users in [Discussions](https://github.com/dbt-msft/dbt-sqlserver/discussions) and on the [dbt Slack](https://getdbt.slack.com/archives/CMRMDDQ9W).
|
|
503
|
+
If you're unsure how to get started, check out our [contributing guide](https://github.com/dbt-msft/dbt-sqlserver/blob/master/CONTRIBUTING.md).
|
|
497
504
|
|
|
498
505
|
## License
|
|
499
506
|
|
|
@@ -39,7 +39,7 @@ We've bundled all documentation on the dbt docs site:
|
|
|
39
39
|
- [Profile setup & authentication](https://docs.getdbt.com/reference/warehouse-profiles/mssql-profile)
|
|
40
40
|
- [Adapter documentation, usage and important notes](https://docs.getdbt.com/reference/resource-configs/mssql-configs)
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Ask questions and get help in [GitHub Discussions](https://github.com/dbt-msft/dbt-sqlserver/discussions/categories/q-a). The [dbt Slack](https://getdbt.slack.com/archives/CMRMDDQ9W) channel is there for chatting with the community.
|
|
43
43
|
|
|
44
44
|
## Installation
|
|
45
45
|
|
|
@@ -128,11 +128,11 @@ An Arrow-native backend built on [ADBC](https://arrow.apache.org/adbc/), avoidin
|
|
|
128
128
|
pip install -U "dbt-sqlserver[adbc]"
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
The driver binary is not on PyPI and must be installed once via the `dbc` CLI. See [docs/adbc_backend.md](docs/adbc_backend.md) for the full setup, configuration, and known-differences guide.
|
|
131
|
+
The driver binary is not on PyPI and must be installed once via the `dbc` CLI. See [docs/adbc_backend.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/adbc_backend.md) for the full setup, configuration, and known-differences guide.
|
|
132
132
|
|
|
133
133
|
## Changelog
|
|
134
134
|
|
|
135
|
-
See [the changelog](CHANGELOG.md)
|
|
135
|
+
See [the changelog](https://github.com/dbt-msft/dbt-sqlserver/blob/master/CHANGELOG.md)
|
|
136
136
|
|
|
137
137
|
## Configuration
|
|
138
138
|
|
|
@@ -163,7 +163,7 @@ The same setting is also honoured via `vars:` for backwards compatibility; the b
|
|
|
163
163
|
|
|
164
164
|
### `backend`
|
|
165
165
|
|
|
166
|
-
*(default: `pyodbc`)* Set to `mssql-python` or `adbc` (experimental, see [docs/adbc_backend.md](docs/adbc_backend.md)) in a profile target to use that backend instead of `pyodbc`. The adapter fails if the required backend package (Python dependency), such as `pyodbc`, `mssql-python`, or `adbc-driver-manager`, is not installed.
|
|
166
|
+
*(default: `pyodbc`)* Set to `mssql-python` or `adbc` (experimental, see [docs/adbc_backend.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/adbc_backend.md)) in a profile target to use that backend instead of `pyodbc`. The adapter fails if the required backend package (Python dependency), such as `pyodbc`, `mssql-python`, or `adbc-driver-manager`, is not installed.
|
|
167
167
|
|
|
168
168
|
### `dbt_sqlserver_enable_safe_type_expansion`
|
|
169
169
|
|
|
@@ -189,7 +189,7 @@ two paths that commit a full-refresh marker before the load
|
|
|
189
189
|
existing table), where neither scope can roll it back. `build` stages
|
|
190
190
|
it inside the hook's transaction, for the one case `load` cannot serve: a
|
|
191
191
|
`transaction: true` pre-hook that creates an object the model reads. See
|
|
192
|
-
[docs/transaction_scope.md](docs/transaction_scope.md) for the full flow and
|
|
192
|
+
[docs/transaction_scope.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/transaction_scope.md) for the full flow and
|
|
193
193
|
the post-hook ordering change.
|
|
194
194
|
|
|
195
195
|
### `dbt_sqlserver_use_dbt_transactions`
|
|
@@ -202,11 +202,12 @@ The driver connection remains in autocommit mode (`autocommit=true`) in both mod
|
|
|
202
202
|
|
|
203
203
|
This is now the default and should be tested carefully with project-specific materializations and hooks. Projects that depend on autocommit-only behavior should set the flag to `false` during migration.
|
|
204
204
|
|
|
205
|
+
**Compatibility notes:** Enabling `dbt_sqlserver_use_dbt_transactions: true` may expose transaction-state assumptions hidden by autocommit-only mode. Explicit transaction macros may interact with dbt-managed transactions, and cleanup after failed DDL/DML may differ. Review pre/post hooks for in-transaction vs out-of-transaction semantics.
|
|
206
|
+
|
|
205
207
|
```yaml
|
|
206
208
|
# dbt_project.yml
|
|
207
209
|
flags:
|
|
208
|
-
|
|
209
|
-
dbt_sqlserver_use_dbt_transactions: true # default
|
|
210
|
+
dbt_sqlserver_use_dbt_transactions: false # legacy autocommit; deprecated
|
|
210
211
|
```
|
|
211
212
|
|
|
212
213
|
### `dbt_sqlserver_use_native_string_types`
|
|
@@ -249,7 +250,11 @@ your_profile:
|
|
|
249
250
|
|
|
250
251
|
### `prefer_single_alter_column`
|
|
251
252
|
|
|
252
|
-
*(default:
|
|
253
|
+
*(default: unset)* Model-level config that controls how `alter_column_type` changes column types on tables:
|
|
254
|
+
|
|
255
|
+
* `true`: a single `ALTER COLUMN` statement. It is atomic, instant for a longer `varchar`/`nvarchar`, and keeps the column's indexes, default constraint and position. It fails for types that cannot be implicitly converted, and changing `varchar` to `nvarchar` on a large clustered columnstore table can fail with Msg 35357 (dictionary size limit).
|
|
256
|
+
* `false`: add a temporary column, copy the data, drop the original and rename. It fails when an index, default constraint or statistics object depends on the column, and it moves the column to the end of the table. A failed attempt no longer blocks the next run.
|
|
257
|
+
* unset (default): `true` when column type expansion widens a column within its type (a longer `varchar`, or `varchar(max)`), `false` for every other change.
|
|
253
258
|
|
|
254
259
|
```sql
|
|
255
260
|
-- In an incremental model
|
|
@@ -257,8 +262,6 @@ your_profile:
|
|
|
257
262
|
prefer_single_alter_column=true) }}
|
|
258
263
|
```
|
|
259
264
|
|
|
260
|
-
**Compatibility notes:** Enabling `dbt_sqlserver_use_dbt_transactions: true` may expose transaction-state assumptions hidden by autocommit-only mode. Explicit transaction macros may interact with dbt-managed transactions, and cleanup after failed DDL/DML may differ. Review pre/post hooks for in-transaction vs out-of-transaction semantics.
|
|
261
|
-
|
|
262
265
|
### `as_columnstore`
|
|
263
266
|
|
|
264
267
|
*(default: `true`)* When building a table, the adapter creates a [clustered columnstore index](https://learn.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-overview) (CCI) on it. Set `as_columnstore: false` to build a plain rowstore table instead.
|
|
@@ -284,6 +287,10 @@ You can also set it per model:
|
|
|
284
287
|
|
|
285
288
|
With `table_refresh_method: dml`, a schema change makes the refresh fall back to a rename-swap. On that run — and only that run — the scratch table is rebuilt the way this adapter builds every other table, so it carries the model's columnstore index, and under an enforced contract its `NOT NULL`s and inline constraints, into the swap. That run therefore executes the model's SQL twice — once for the `SELECT … INTO` that probes for the schema change, once for the rebuild — and builds the columnstore index once. Steady-state refreshes are unaffected and keep the single `SELECT … INTO`. A table that lost its columnstore index to this bug before you upgraded is not repaired automatically: its schema still matches, so it stays on the cheap path. To rebuild it, temporarily set `full_refresh_build: prebuilt` and run with `--full-refresh`.
|
|
286
289
|
|
|
290
|
+
### Ephemeral models
|
|
291
|
+
|
|
292
|
+
Ephemeral models are supported, with one limit: an ephemeral model can't start with its own `WITH`. dbt inlines it as a CTE, and T-SQL can't nest a `WITH` inside one (still true on SQL Server 2025). Write it with derived tables instead, or materialize it as a `view`, which SQL Server expands into the calling query the same way.
|
|
293
|
+
|
|
287
294
|
### Constraints
|
|
288
295
|
|
|
289
296
|
Constraints declared in a model's yaml are applied when — and only when — the model's [contract](https://docs.getdbt.com/reference/resource-configs/contract) is enforced, which is what every dbt adapter does and keeps their cost opt-in. (dbt-core does not raise if you declare constraints with the contract off — they are simply never emitted.) `not_null`, `check`, `unique`, `primary_key` and `foreign_key` are all supported.
|
|
@@ -296,7 +303,7 @@ A *model-level* constraint carrying `name:` is applied by `ALTER TABLE … ADD C
|
|
|
296
303
|
|
|
297
304
|
Name a constraint when you want it stable across environments (schema-comparison tools report the generated names as differences) or need to reference it later. A `name:` on a *column-level* constraint is ignored with a warning — declare it under the model's `constraints:` key instead.
|
|
298
305
|
|
|
299
|
-
The full set of rules, with the test that verifies each, is in [docs/constraints.md](docs/constraints.md).
|
|
306
|
+
The full set of rules, with the test that verifies each, is in [docs/constraints.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/constraints.md).
|
|
300
307
|
|
|
301
308
|
```yaml
|
|
302
309
|
models:
|
|
@@ -454,8 +461,8 @@ The `denies` config re-applies object-level DENYs after each build, diffed again
|
|
|
454
461
|
[](https://github.com/dbt-msft/dbt-sqlserver/actions/workflows/integration-tests-sqlserver.yml)
|
|
455
462
|
|
|
456
463
|
This adapter is community-maintained.
|
|
457
|
-
You are welcome to contribute by creating issues, opening or reviewing pull requests, or helping other users in the Slack
|
|
458
|
-
If you're unsure how to get started, check out our [contributing guide](CONTRIBUTING.md).
|
|
464
|
+
You are welcome to contribute by creating issues, opening or reviewing pull requests, or helping other users in [Discussions](https://github.com/dbt-msft/dbt-sqlserver/discussions) and on the [dbt Slack](https://getdbt.slack.com/archives/CMRMDDQ9W).
|
|
465
|
+
If you're unsure how to get started, check out our [contributing guide](https://github.com/dbt-msft/dbt-sqlserver/blob/master/CONTRIBUTING.md).
|
|
459
466
|
|
|
460
467
|
## License
|
|
461
468
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "1.12.2"
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_adapter.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import datetime as _dt
|
|
2
2
|
import re
|
|
3
|
-
from
|
|
3
|
+
from contextlib import contextmanager
|
|
4
|
+
from typing import Any, Dict, Iterator, List, Optional, Tuple, Type, Union
|
|
4
5
|
|
|
5
6
|
import agate
|
|
6
7
|
import dbt_common.exceptions
|
|
@@ -446,8 +447,15 @@ class SQLServerAdapter(SQLAdapter):
|
|
|
446
447
|
|
|
447
448
|
@classmethod
|
|
448
449
|
def convert_number_type(cls, agate_table, col_idx):
|
|
449
|
-
|
|
450
|
-
|
|
450
|
+
if agate_table.aggregate(agate.MaxPrecision(col_idx)):
|
|
451
|
+
return "float"
|
|
452
|
+
values = agate_table.columns[col_idx].values_without_nulls()
|
|
453
|
+
low, high = (min(values), max(values)) if values else (0, 0)
|
|
454
|
+
if -(2**31) <= low and high < 2**31:
|
|
455
|
+
return "int"
|
|
456
|
+
if -(2**63) <= low and high < 2**63:
|
|
457
|
+
return "bigint"
|
|
458
|
+
return "numeric(38,0)"
|
|
451
459
|
|
|
452
460
|
def create_schema(self, relation: BaseRelation) -> None:
|
|
453
461
|
relation = relation.without_identifier()
|
|
@@ -470,6 +478,8 @@ class SQLServerAdapter(SQLAdapter):
|
|
|
470
478
|
# see https://github.com/fishtown-analytics/dbt/pull/2255
|
|
471
479
|
lens = [len(d.encode("utf-8")) for d in column.values_without_nulls()]
|
|
472
480
|
max_len = max(lens) if lens else 64
|
|
481
|
+
if max_len > 8000:
|
|
482
|
+
return "varchar(max)"
|
|
473
483
|
length = max_len if max_len > 16 else 16
|
|
474
484
|
return "varchar({})".format(length)
|
|
475
485
|
|
|
@@ -828,13 +838,27 @@ class SQLServerAdapter(SQLAdapter):
|
|
|
828
838
|
|
|
829
839
|
return True
|
|
830
840
|
|
|
831
|
-
def expand_column_types(
|
|
841
|
+
def expand_column_types(
|
|
842
|
+
self,
|
|
843
|
+
goal,
|
|
844
|
+
current,
|
|
845
|
+
max_rows: int = 1000000,
|
|
846
|
+
prefer_single_alter_column: Optional[bool] = None,
|
|
847
|
+
):
|
|
832
848
|
"""Widen ``current``'s columns to match ``goal``, preserving the
|
|
833
849
|
nvarchar / nchar family.
|
|
834
850
|
|
|
835
851
|
Same-family resizes (a longer varchar) always proceed. Cross-family
|
|
836
852
|
promotions (varchar -> nvarchar) are opt-in and gated; see
|
|
837
853
|
``_safe_expansion_allowed``.
|
|
854
|
+
|
|
855
|
+
``prefer_single_alter_column`` is the model's config. Unset, a
|
|
856
|
+
same-family resize uses a single ``ALTER COLUMN``: metadata-only for a
|
|
857
|
+
longer varchar, atomic, and it keeps indexes, defaults and column
|
|
858
|
+
position, all of which block or move the four-step rewrite. A
|
|
859
|
+
cross-family promotion keeps the four-step path, since a single
|
|
860
|
+
``ALTER COLUMN`` to nvarchar on a large columnstore table can fail
|
|
861
|
+
with Msg 35357 (dictionary size limit).
|
|
838
862
|
"""
|
|
839
863
|
|
|
840
864
|
reference_columns = {c.name: c for c in self.get_columns_in_relation(goal)}
|
|
@@ -847,8 +871,9 @@ class SQLServerAdapter(SQLAdapter):
|
|
|
847
871
|
if target_column is None:
|
|
848
872
|
continue
|
|
849
873
|
|
|
874
|
+
same_family = target_column.can_expand_to(reference_column)
|
|
850
875
|
if not (
|
|
851
|
-
|
|
876
|
+
same_family
|
|
852
877
|
or (safe_expansion_allowed and target_column.can_expand_safe(reference_column))
|
|
853
878
|
):
|
|
854
879
|
continue
|
|
@@ -865,11 +890,46 @@ class SQLServerAdapter(SQLAdapter):
|
|
|
865
890
|
table=_make_ref_key_dict(current),
|
|
866
891
|
)
|
|
867
892
|
)
|
|
868
|
-
|
|
893
|
+
prefer_single = (
|
|
894
|
+
same_family if prefer_single_alter_column is None else prefer_single_alter_column
|
|
895
|
+
)
|
|
896
|
+
self.alter_column_type(current, column_name, new_type, prefer_single)
|
|
897
|
+
|
|
898
|
+
def alter_column_type(
|
|
899
|
+
self,
|
|
900
|
+
relation,
|
|
901
|
+
column_name,
|
|
902
|
+
new_column_type,
|
|
903
|
+
prefer_single_alter_column: Optional[bool] = None,
|
|
904
|
+
) -> None:
|
|
905
|
+
"""Pass the model's ``prefer_single_alter_column`` to the macro.
|
|
906
|
+
|
|
907
|
+
A macro run from Python sees no model config, so
|
|
908
|
+
``config.get('prefer_single_alter_column')`` inside it is always the
|
|
909
|
+
default; and dbt-adapters' ``alter_column_type`` dispatcher forwards
|
|
910
|
+
only the three standard arguments. When the setting is known, call
|
|
911
|
+
the SQL Server implementation with it directly (dbt-msft/dbt-sqlserver#836).
|
|
912
|
+
"""
|
|
913
|
+
if prefer_single_alter_column is None:
|
|
914
|
+
super().alter_column_type(relation, column_name, new_column_type)
|
|
915
|
+
return
|
|
916
|
+
self.execute_macro(
|
|
917
|
+
"sqlserver__alter_column_type",
|
|
918
|
+
kwargs={
|
|
919
|
+
"relation": relation,
|
|
920
|
+
"column_name": column_name,
|
|
921
|
+
"new_column_type": new_column_type,
|
|
922
|
+
"prefer_single": prefer_single_alter_column,
|
|
923
|
+
},
|
|
924
|
+
)
|
|
869
925
|
|
|
870
926
|
@available.parse_none
|
|
871
927
|
def expand_target_column_types(
|
|
872
|
-
self,
|
|
928
|
+
self,
|
|
929
|
+
from_relation: BaseRelation,
|
|
930
|
+
to_relation: BaseRelation,
|
|
931
|
+
max_rows: int = 1000000,
|
|
932
|
+
prefer_single_alter_column: Optional[bool] = None,
|
|
873
933
|
) -> None:
|
|
874
934
|
if not isinstance(from_relation, self.Relation):
|
|
875
935
|
from dbt.adapters.base.impl import MacroArgTypeError
|
|
@@ -889,7 +949,7 @@ class SQLServerAdapter(SQLAdapter):
|
|
|
889
949
|
got_value=to_relation,
|
|
890
950
|
expected_type=self.Relation,
|
|
891
951
|
)
|
|
892
|
-
self.expand_column_types(from_relation, to_relation, max_rows)
|
|
952
|
+
self.expand_column_types(from_relation, to_relation, max_rows, prefer_single_alter_column)
|
|
893
953
|
|
|
894
954
|
@available
|
|
895
955
|
def parse_index(self, raw_index: Any) -> Optional[SQLServerIndexConfig]:
|
|
@@ -906,6 +966,28 @@ class SQLServerAdapter(SQLAdapter):
|
|
|
906
966
|
return False
|
|
907
967
|
return create_needs_own_batch(parsed.build_options)
|
|
908
968
|
|
|
969
|
+
# dbt-core's run-operation runs on connections with these names.
|
|
970
|
+
_RUN_OPERATION_CONNECTION_PREFIXES = ("macro_", "inline_query")
|
|
971
|
+
|
|
972
|
+
@contextmanager
|
|
973
|
+
def connection_named(
|
|
974
|
+
self, name: str, query_header_context: Any = None, should_release_connection: bool = True
|
|
975
|
+
) -> Iterator[None]:
|
|
976
|
+
"""Commit a run-operation's open transaction when it finishes cleanly.
|
|
977
|
+
|
|
978
|
+
Stopgap for dbt-labs/dbt#16434, remove once dbt-core commits after a
|
|
979
|
+
run-operation: dbt-core never does, so with dbt-managed transactions
|
|
980
|
+
on, a write through ``statement()`` (auto_begin) is rolled back when
|
|
981
|
+
the connection closes. The commit sits after the ``yield`` so it runs
|
|
982
|
+
only when the macro did not raise; a failed macro still rolls back.
|
|
983
|
+
Matching on the connection name is a heuristic, since dbt-core marks
|
|
984
|
+
run-operation connections no other way.
|
|
985
|
+
"""
|
|
986
|
+
with super().connection_named(name, query_header_context, should_release_connection):
|
|
987
|
+
yield
|
|
988
|
+
if name.startswith(self._RUN_OPERATION_CONNECTION_PREFIXES):
|
|
989
|
+
self.commit_if_open()
|
|
990
|
+
|
|
909
991
|
@available
|
|
910
992
|
def commit_if_open(self) -> None:
|
|
911
993
|
"""Commit the current transaction if one is open - a no-op otherwise.
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_configs.py
RENAMED
|
@@ -10,7 +10,8 @@ from dbt.adapters.sqlserver.relation_configs import SQLServerIndexConfig
|
|
|
10
10
|
@dataclass
|
|
11
11
|
class SQLServerConfigs(AdapterConfig):
|
|
12
12
|
auto_provision_aad_principals: Optional[bool] = False
|
|
13
|
-
|
|
13
|
+
# unset: single ALTER COLUMN for same-family widening, four-step otherwise
|
|
14
|
+
prefer_single_alter_column: Optional[bool] = None
|
|
14
15
|
column_type_expansion_max_rows: int = 1000000
|
|
15
16
|
indexes: Optional[Tuple[SQLServerIndexConfig, ...]] = None
|
|
16
17
|
# false (default) | warn | true - how index reconciliation treats
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/columns.sql
RENAMED
|
@@ -36,19 +36,38 @@
|
|
|
36
36
|
{% endif %}
|
|
37
37
|
{% endmacro %}
|
|
38
38
|
|
|
39
|
-
{% macro sqlserver__alter_column_type(relation, column_name, new_column_type) %}
|
|
39
|
+
{% macro sqlserver__alter_column_type(relation, column_name, new_column_type, prefer_single=none) %}
|
|
40
40
|
|
|
41
|
-
{
|
|
41
|
+
{#-- Called from Python (expand_target_column_types) the macro sees no model config, so the adapter passes prefer_single in (dbt-msft/dbt-sqlserver#836) --#}
|
|
42
|
+
{% if prefer_single is none %}
|
|
43
|
+
{% set prefer_single = config.get('prefer_single_alter_column', false) %}
|
|
44
|
+
{% endif %}
|
|
45
|
+
|
|
46
|
+
{#-- ALTER COLUMN without NOT NULL makes the column nullable --#}
|
|
47
|
+
{% set nullable_sql %}
|
|
48
|
+
{{ get_use_database_sql(relation.database) }}
|
|
49
|
+
select columnproperty(object_id('{{ escape_single_quotes(relation) }}'), '{{ escape_single_quotes(column_name) }}', 'AllowsNull')
|
|
50
|
+
{%- endset %}
|
|
51
|
+
{%- set not_null = run_query(nullable_sql).columns[0].values()[0] == 0 -%}
|
|
42
52
|
|
|
43
53
|
{% if prefer_single and relation.type == 'table' %}
|
|
44
54
|
{% set alter_sql %}
|
|
45
55
|
alter {{ relation.type }} {{ relation }}
|
|
46
|
-
alter column "{{ column_name }}" {{ new_column_type }};
|
|
56
|
+
alter column "{{ column_name }}" {{ new_column_type }}{{ ' not null' if not_null }};
|
|
47
57
|
{%- endset %}
|
|
48
58
|
{% do run_query(alter_sql) %}
|
|
49
59
|
|
|
50
60
|
{% else %}
|
|
51
61
|
{%- set tmp_column = column_name + "__dbt_alter" -%}
|
|
62
|
+
{%- set relation_name = escape_single_quotes(relation.include(database=False)) -%}
|
|
63
|
+
|
|
64
|
+
{#-- The four steps below autocommit one by one, so a failed run can leave tmp_column behind, and the next run's ADD then fails forever (dbt-msft/dbt-sqlserver#836).
|
|
65
|
+
Drop it first. It is only a partial copy while the original column still exists; if the original is gone, tmp_column holds the data, so it is left alone. --#}
|
|
66
|
+
{% set drop_leftover %}
|
|
67
|
+
if col_length('{{ relation_name }}', '{{ escape_single_quotes(tmp_column) }}') is not null
|
|
68
|
+
and col_length('{{ relation_name }}', '{{ escape_single_quotes(column_name) }}') is not null
|
|
69
|
+
alter {{ relation.type }} {{ relation }} drop column "{{ tmp_column }}";
|
|
70
|
+
{%- endset %}
|
|
52
71
|
|
|
53
72
|
{% set add_column %}
|
|
54
73
|
alter {{ relation.type }} {{ relation }}
|
|
@@ -62,13 +81,21 @@
|
|
|
62
81
|
drop column "{{ column_name }}";
|
|
63
82
|
{%- endset %}
|
|
64
83
|
{% set rename_column %}
|
|
65
|
-
exec sp_rename '{{
|
|
84
|
+
exec sp_rename '{{ relation_name }}.{{ escape_single_quotes(adapter.quote(tmp_column)) }}', '{{ escape_single_quotes(column_name) }}', 'column'
|
|
85
|
+
{%- endset %}
|
|
86
|
+
{% set alter_sql_not_null %}
|
|
87
|
+
alter {{ relation.type }} {{ relation }}
|
|
88
|
+
alter column "{{ column_name }}" {{ new_column_type }} not null;
|
|
66
89
|
{%- endset %}
|
|
67
90
|
|
|
91
|
+
{% do run_query(drop_leftover) %}
|
|
68
92
|
{% do run_query(add_column) %}
|
|
69
93
|
{% do run_query(update_column) %}
|
|
70
94
|
{% do run_query(drop_column) %}
|
|
71
95
|
{% do run_query(rename_column) %}
|
|
96
|
+
{% if not_null %}
|
|
97
|
+
{% do run_query(alter_sql_not_null) %}
|
|
98
|
+
{% endif %}
|
|
72
99
|
{% endif %}
|
|
73
100
|
|
|
74
101
|
{% endmacro %}
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/metadata.sql
RENAMED
|
@@ -197,11 +197,13 @@
|
|
|
197
197
|
- dm_exec_describe_first_result_set is referenced once: each reference compiles the body.
|
|
198
198
|
- Its error row is kept, so a body it cannot describe is refreshed.
|
|
199
199
|
- COLLATE DATABASE_DEFAULT, or the join fails where catalog and database collations differ.
|
|
200
|
-
-
|
|
200
|
+
- Run through sp_executesql, so the statement text is the same for every view and SQL
|
|
201
|
+
Server caches one plan for all of them.
|
|
202
|
+
- The values are inlined, typed by the parameter list: the function needs nvarchar and
|
|
203
|
+
mssql-python binds str as varchar. -#}
|
|
201
204
|
{% macro sqlserver__get_view_skip_check_sql(relation, compiled_sql) -%}
|
|
202
|
-
{%- set object_name = "quotename(
|
|
203
|
-
{
|
|
204
|
-
declare @dbt_sqlserver_skip_check_body nvarchar(max) = N'{{ escape_single_quotes(compiled_sql) }}';
|
|
205
|
+
{%- set object_name = "quotename(@schema) + '.' + quotename(@identifier)" -%}
|
|
206
|
+
{%- set check_sql -%}
|
|
205
207
|
select
|
|
206
208
|
object_definition(object_id({{ object_name }}, 'V')) as definition,
|
|
207
209
|
case when exists (
|
|
@@ -234,6 +236,13 @@
|
|
|
234
236
|
<> isnull(cached.collation_name, '') collate database_default
|
|
235
237
|
) then 1 else 0 end as needs_refresh
|
|
236
238
|
where object_id({{ object_name }}, 'V') is not null
|
|
239
|
+
{%- endset -%}
|
|
240
|
+
{{ get_use_database_sql(relation.database) }}
|
|
241
|
+
exec sp_executesql N'{{ escape_single_quotes(check_sql) }}',
|
|
242
|
+
N'@schema sysname, @identifier sysname, @dbt_sqlserver_skip_check_body nvarchar(max)',
|
|
243
|
+
@schema = N'{{ escape_single_quotes(relation.schema) }}',
|
|
244
|
+
@identifier = N'{{ escape_single_quotes(relation.identifier) }}',
|
|
245
|
+
@dbt_sqlserver_skip_check_body = N'{{ escape_single_quotes(compiled_sql) }}';
|
|
237
246
|
{% endmacro %}
|
|
238
247
|
|
|
239
248
|
{% macro sqlserver__get_relation_last_modified(information_schema, relations) -%}
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/relation.sql
RENAMED
|
@@ -8,14 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
{% macro sqlserver__get_drop_sql(relation) -%}
|
|
10
10
|
{% if relation.type == 'view' -%}
|
|
11
|
-
{#-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
adapter.drop_relation), so with the default auto_begin=True it held
|
|
15
|
-
that build's sys.sysschobjs X locks until the materialization
|
|
16
|
-
committed, deadlocking a concurrent worker (error 1205). -#}
|
|
17
|
-
{% call statement('find_references', fetch_result=true, auto_begin=false) %}
|
|
18
|
-
{{ get_use_database_sql(relation.database) }}
|
|
11
|
+
{#- Run through sp_executesql, so the statement text is the same for every
|
|
12
|
+
relation and SQL Server caches one plan for all of them. -#}
|
|
13
|
+
{%- set find_references_sql -%}
|
|
19
14
|
select
|
|
20
15
|
sch.name as schema_name,
|
|
21
16
|
obj.name as view_name
|
|
@@ -24,11 +19,25 @@
|
|
|
24
19
|
on refs.referencing_id = obj.object_id
|
|
25
20
|
inner join sys.schemas sch {{ information_schema_hints() }}
|
|
26
21
|
on obj.schema_id = sch.schema_id
|
|
27
|
-
where refs.referenced_database_name =
|
|
28
|
-
and refs.referenced_schema_name =
|
|
29
|
-
and refs.referenced_entity_name =
|
|
22
|
+
where refs.referenced_database_name = @database
|
|
23
|
+
and refs.referenced_schema_name = @schema
|
|
24
|
+
and refs.referenced_entity_name = @identifier
|
|
30
25
|
and obj.type = 'V'
|
|
31
26
|
{{ get_query_options() }}
|
|
27
|
+
{%- endset %}
|
|
28
|
+
{#- auto_begin=false, matching dbt-adapters' own relations/drop.sql: a
|
|
29
|
+
read-only lookup must not open the ambient transaction. This is the
|
|
30
|
+
first statement of the temp-relation build (create.sql ->
|
|
31
|
+
adapter.drop_relation), so with the default auto_begin=True it held
|
|
32
|
+
that build's sys.sysschobjs X locks until the materialization
|
|
33
|
+
committed, deadlocking a concurrent worker (error 1205). -#}
|
|
34
|
+
{% call statement('find_references', fetch_result=true, auto_begin=false) %}
|
|
35
|
+
{{ get_use_database_sql(relation.database) }}
|
|
36
|
+
exec sp_executesql N'{{ escape_single_quotes(find_references_sql) }}',
|
|
37
|
+
N'@database sysname, @schema sysname, @identifier sysname',
|
|
38
|
+
@database = N'{{ escape_single_quotes(relation.database) }}',
|
|
39
|
+
@schema = N'{{ escape_single_quotes(relation.schema) }}',
|
|
40
|
+
@identifier = N'{{ escape_single_quotes(relation.identifier) }}';
|
|
32
41
|
{% endcall %}
|
|
33
42
|
{% set references = load_result('find_references')['data'] %}
|
|
34
43
|
{% for reference in references -%}
|
|
@@ -175,7 +175,8 @@
|
|
|
175
175
|
{% do adapter.expand_target_column_types(
|
|
176
176
|
from_relation=temp_relation,
|
|
177
177
|
to_relation=target_relation,
|
|
178
|
-
max_rows=expansion_max_rows
|
|
178
|
+
max_rows=expansion_max_rows,
|
|
179
|
+
prefer_single_alter_column=config.get('prefer_single_alter_column')) %}
|
|
179
180
|
{% endif %}
|
|
180
181
|
{#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}
|
|
181
182
|
{% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
{% if unique_key %}
|
|
16
16
|
{% if unique_key is sequence and unique_key is not string %}
|
|
17
17
|
SET NOCOUNT ON;
|
|
18
|
-
delete from {{ target }}
|
|
18
|
+
delete DBT_INTERNAL_DEST from {{ target }} as DBT_INTERNAL_DEST
|
|
19
19
|
where exists (
|
|
20
20
|
select null
|
|
21
21
|
from {{ source }}
|
|
22
22
|
where
|
|
23
23
|
{% for key in unique_key %}
|
|
24
|
-
{{ source }}.{{ key }} =
|
|
24
|
+
{{ source }}.{{ key }} = DBT_INTERNAL_DEST.{{ key }}
|
|
25
25
|
{{ "and " if not loop.last }}
|
|
26
26
|
{% endfor %}
|
|
27
27
|
)
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
SET NOCOUNT OFF;
|
|
35
35
|
{% else %}
|
|
36
36
|
SET NOCOUNT ON;
|
|
37
|
-
delete from {{ target }}
|
|
37
|
+
delete DBT_INTERNAL_DEST from {{ target }} as DBT_INTERNAL_DEST
|
|
38
38
|
where (
|
|
39
39
|
{{ unique_key }}) in (
|
|
40
40
|
select ({{ unique_key }})
|
|
@@ -134,7 +134,11 @@
|
|
|
134
134
|
|
|
135
135
|
{{ adapter.commit() }}
|
|
136
136
|
|
|
137
|
-
{
|
|
137
|
+
{#- Only the table branch above makes a backup. A view is altered in place, and a
|
|
138
|
+
drop would still query the missing backup's dependents. -#}
|
|
139
|
+
{% if existing_relation is not none and existing_relation.type != 'view' %}
|
|
140
|
+
{{ drop_relation_if_exists(backup_relation) }}
|
|
141
|
+
{% endif %}
|
|
138
142
|
|
|
139
143
|
{{ run_hooks(post_hooks, inside_transaction=False) }}
|
|
140
144
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{% macro sqlserver__create_columns(relation, columns) %}
|
|
2
2
|
{% set column_list %}
|
|
3
3
|
{% for column_entry in columns %}
|
|
4
|
-
{{column_entry.name}} {{column_entry.data_type}}{{ ", " if not loop.last }}
|
|
4
|
+
{{ adapter.quote(column_entry.name) }} {{column_entry.data_type}}{{ ", " if not loop.last }}
|
|
5
5
|
{% endfor %}
|
|
6
6
|
{% endset %}
|
|
7
7
|
|
|
@@ -115,7 +115,8 @@
|
|
|
115
115
|
{% set expansion_max_rows = config.get('column_type_expansion_max_rows', 1000000) %}
|
|
116
116
|
{% do adapter.expand_target_column_types(from_relation=staging_table,
|
|
117
117
|
to_relation=target_relation,
|
|
118
|
-
max_rows=expansion_max_rows
|
|
118
|
+
max_rows=expansion_max_rows,
|
|
119
|
+
prefer_single_alter_column=config.get('prefer_single_alter_column')) %}
|
|
119
120
|
|
|
120
121
|
{% set remove_columns = ['dbt_change_type', 'DBT_CHANGE_TYPE', 'dbt_unique_key', 'DBT_UNIQUE_KEY'] %}
|
|
121
122
|
{% if unique_key | is_list %}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{% macro sqlserver__snapshot_hash_arguments(args) %}
|
|
2
|
+
CONVERT(VARCHAR(32), HashBytes('MD5', {% for arg in args %}
|
|
3
|
+
coalesce(cast({{ arg }} as varchar(8000)), '') {% if not loop.last %} + '|' + {% endif %}
|
|
4
|
+
{% endfor %}), 2)
|
|
5
|
+
{% endmacro %}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
{#
|
|
9
|
+
dbt-adapters does not dispatch "snapshot_check_all_get_existing_columns", so
|
|
10
|
+
this shadows the global project's macro; adapter package macros take
|
|
11
|
+
precedence. Keep in sync with dbt-adapters when upgrading. When upstream
|
|
12
|
+
dispatches it, delete the public wrapper and keep the sqlserver__ handler.
|
|
13
|
+
|
|
14
|
+
Change from upstream: for a check_cols list, upstream reads the columns'
|
|
15
|
+
casing from "select <check_cols> from (<sql>) subq", and T-SQL can't nest a
|
|
16
|
+
WITH in a subquery. This reads the query's columns unwrapped, as the 'all'
|
|
17
|
+
branch does, and picks check_cols from them case-insensitively.
|
|
18
|
+
#}
|
|
19
|
+
|
|
20
|
+
{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}
|
|
21
|
+
{{ return(sqlserver__snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config)) }}
|
|
22
|
+
{%- endmacro %}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
{% macro sqlserver__snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}
|
|
26
|
+
{%- if not target_exists -%}
|
|
27
|
+
{#-- no table yet -> return whatever the query does --#}
|
|
28
|
+
{{ return((false, query_columns)) }}
|
|
29
|
+
{%- endif -%}
|
|
30
|
+
|
|
31
|
+
{#-- handle any schema changes --#}
|
|
32
|
+
{%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}
|
|
33
|
+
|
|
34
|
+
{% if check_cols_config == 'all' %}
|
|
35
|
+
{%- set query_columns = get_columns_in_query(node['compiled_code']) -%}
|
|
36
|
+
|
|
37
|
+
{% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}
|
|
38
|
+
{%- set all_columns = get_columns_in_query(node['compiled_code']) -%}
|
|
39
|
+
{%- set all_columns_lower = all_columns | map('lower') | list -%}
|
|
40
|
+
{%- set query_columns = [] -%}
|
|
41
|
+
{%- for check_col in check_cols_config -%}
|
|
42
|
+
{%- if (check_col | lower) not in all_columns_lower -%}
|
|
43
|
+
{% do exceptions.raise_compiler_error("check_cols column '" ~ check_col ~ "' is not in the snapshot query") %}
|
|
44
|
+
{%- endif -%}
|
|
45
|
+
{%- do query_columns.append(all_columns[all_columns_lower.index(check_col | lower)]) -%}
|
|
46
|
+
{%- endfor -%}
|
|
47
|
+
|
|
48
|
+
{% else %}
|
|
49
|
+
{% do exceptions.raise_compiler_error("Invalid value for 'check_cols': " ~ check_cols_config) %}
|
|
50
|
+
{% endif %}
|
|
51
|
+
|
|
52
|
+
{%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}
|
|
53
|
+
{%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}
|
|
54
|
+
{%- set ns.column_added = false -%}
|
|
55
|
+
|
|
56
|
+
{%- set intersection = [] -%}
|
|
57
|
+
{%- for col in query_columns -%}
|
|
58
|
+
{%- if col in existing_cols -%}
|
|
59
|
+
{%- do intersection.append(adapter.quote(col)) -%}
|
|
60
|
+
{%- else -%}
|
|
61
|
+
{% set ns.column_added = true %}
|
|
62
|
+
{%- endif -%}
|
|
63
|
+
{%- endfor -%}
|
|
64
|
+
{{ return((ns.column_added, intersection)) }}
|
|
65
|
+
{%- endmacro %}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
{%- materialization unit, adapter='sqlserver' -%}
|
|
2
|
+
{#- The default drops its fixture table inside the transaction
|
|
3
|
+
statement('main') opens and never commits, so with
|
|
4
|
+
dbt_sqlserver_use_dbt_transactions on the drop rolls back
|
|
5
|
+
(dbt-labs/dbt#16499). -#}
|
|
6
|
+
{% set relations = materialization_unit_default() %}
|
|
7
|
+
{% do adapter.commit_if_open() %}
|
|
8
|
+
{{ return(relations) }}
|
|
9
|
+
{%- endmaterialization -%}
|
|
10
|
+
|
|
1
11
|
{% macro sqlserver__get_unit_test_sql(main_sql, expected_fixture_sql, expected_column_names) -%}
|
|
2
12
|
|
|
3
13
|
{{ get_use_database_sql(target.database) }}
|
|
@@ -35,7 +35,11 @@
|
|
|
35
35
|
{{ get_assert_columns_equivalent(sql) }}
|
|
36
36
|
{{ build_columns_constraints(relation) }}
|
|
37
37
|
{%- else -%}
|
|
38
|
+
{#- the UNION ALL keeps SELECT INTO from copying an IDENTITY column, which the
|
|
39
|
+
load's explicit ids would then violate; nullability and types are unchanged -#}
|
|
38
40
|
SELECT TOP 0 * INTO {{ relation }} FROM {{ tmp_relation }}
|
|
41
|
+
UNION ALL
|
|
42
|
+
SELECT TOP 0 * FROM {{ tmp_relation }}
|
|
39
43
|
{%- endif -%}
|
|
40
44
|
{%- endmacro %}
|
|
41
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbt-sqlserver
|
|
3
|
-
Version: 1.12.
|
|
3
|
+
Version: 1.12.2
|
|
4
4
|
Summary: A Microsoft SQL Server adapter plugin for dbt
|
|
5
5
|
Author: Mikael Ene, Anders Swanson, Sam Debruyn, Cor Zuurmond, Cody Scott
|
|
6
6
|
License: MIT
|
|
@@ -77,7 +77,7 @@ We've bundled all documentation on the dbt docs site:
|
|
|
77
77
|
- [Profile setup & authentication](https://docs.getdbt.com/reference/warehouse-profiles/mssql-profile)
|
|
78
78
|
- [Adapter documentation, usage and important notes](https://docs.getdbt.com/reference/resource-configs/mssql-configs)
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
Ask questions and get help in [GitHub Discussions](https://github.com/dbt-msft/dbt-sqlserver/discussions/categories/q-a). The [dbt Slack](https://getdbt.slack.com/archives/CMRMDDQ9W) channel is there for chatting with the community.
|
|
81
81
|
|
|
82
82
|
## Installation
|
|
83
83
|
|
|
@@ -166,11 +166,11 @@ An Arrow-native backend built on [ADBC](https://arrow.apache.org/adbc/), avoidin
|
|
|
166
166
|
pip install -U "dbt-sqlserver[adbc]"
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
The driver binary is not on PyPI and must be installed once via the `dbc` CLI. See [docs/adbc_backend.md](docs/adbc_backend.md) for the full setup, configuration, and known-differences guide.
|
|
169
|
+
The driver binary is not on PyPI and must be installed once via the `dbc` CLI. See [docs/adbc_backend.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/adbc_backend.md) for the full setup, configuration, and known-differences guide.
|
|
170
170
|
|
|
171
171
|
## Changelog
|
|
172
172
|
|
|
173
|
-
See [the changelog](CHANGELOG.md)
|
|
173
|
+
See [the changelog](https://github.com/dbt-msft/dbt-sqlserver/blob/master/CHANGELOG.md)
|
|
174
174
|
|
|
175
175
|
## Configuration
|
|
176
176
|
|
|
@@ -201,7 +201,7 @@ The same setting is also honoured via `vars:` for backwards compatibility; the b
|
|
|
201
201
|
|
|
202
202
|
### `backend`
|
|
203
203
|
|
|
204
|
-
*(default: `pyodbc`)* Set to `mssql-python` or `adbc` (experimental, see [docs/adbc_backend.md](docs/adbc_backend.md)) in a profile target to use that backend instead of `pyodbc`. The adapter fails if the required backend package (Python dependency), such as `pyodbc`, `mssql-python`, or `adbc-driver-manager`, is not installed.
|
|
204
|
+
*(default: `pyodbc`)* Set to `mssql-python` or `adbc` (experimental, see [docs/adbc_backend.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/adbc_backend.md)) in a profile target to use that backend instead of `pyodbc`. The adapter fails if the required backend package (Python dependency), such as `pyodbc`, `mssql-python`, or `adbc-driver-manager`, is not installed.
|
|
205
205
|
|
|
206
206
|
### `dbt_sqlserver_enable_safe_type_expansion`
|
|
207
207
|
|
|
@@ -227,7 +227,7 @@ two paths that commit a full-refresh marker before the load
|
|
|
227
227
|
existing table), where neither scope can roll it back. `build` stages
|
|
228
228
|
it inside the hook's transaction, for the one case `load` cannot serve: a
|
|
229
229
|
`transaction: true` pre-hook that creates an object the model reads. See
|
|
230
|
-
[docs/transaction_scope.md](docs/transaction_scope.md) for the full flow and
|
|
230
|
+
[docs/transaction_scope.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/transaction_scope.md) for the full flow and
|
|
231
231
|
the post-hook ordering change.
|
|
232
232
|
|
|
233
233
|
### `dbt_sqlserver_use_dbt_transactions`
|
|
@@ -240,11 +240,12 @@ The driver connection remains in autocommit mode (`autocommit=true`) in both mod
|
|
|
240
240
|
|
|
241
241
|
This is now the default and should be tested carefully with project-specific materializations and hooks. Projects that depend on autocommit-only behavior should set the flag to `false` during migration.
|
|
242
242
|
|
|
243
|
+
**Compatibility notes:** Enabling `dbt_sqlserver_use_dbt_transactions: true` may expose transaction-state assumptions hidden by autocommit-only mode. Explicit transaction macros may interact with dbt-managed transactions, and cleanup after failed DDL/DML may differ. Review pre/post hooks for in-transaction vs out-of-transaction semantics.
|
|
244
|
+
|
|
243
245
|
```yaml
|
|
244
246
|
# dbt_project.yml
|
|
245
247
|
flags:
|
|
246
|
-
|
|
247
|
-
dbt_sqlserver_use_dbt_transactions: true # default
|
|
248
|
+
dbt_sqlserver_use_dbt_transactions: false # legacy autocommit; deprecated
|
|
248
249
|
```
|
|
249
250
|
|
|
250
251
|
### `dbt_sqlserver_use_native_string_types`
|
|
@@ -287,7 +288,11 @@ your_profile:
|
|
|
287
288
|
|
|
288
289
|
### `prefer_single_alter_column`
|
|
289
290
|
|
|
290
|
-
*(default:
|
|
291
|
+
*(default: unset)* Model-level config that controls how `alter_column_type` changes column types on tables:
|
|
292
|
+
|
|
293
|
+
* `true`: a single `ALTER COLUMN` statement. It is atomic, instant for a longer `varchar`/`nvarchar`, and keeps the column's indexes, default constraint and position. It fails for types that cannot be implicitly converted, and changing `varchar` to `nvarchar` on a large clustered columnstore table can fail with Msg 35357 (dictionary size limit).
|
|
294
|
+
* `false`: add a temporary column, copy the data, drop the original and rename. It fails when an index, default constraint or statistics object depends on the column, and it moves the column to the end of the table. A failed attempt no longer blocks the next run.
|
|
295
|
+
* unset (default): `true` when column type expansion widens a column within its type (a longer `varchar`, or `varchar(max)`), `false` for every other change.
|
|
291
296
|
|
|
292
297
|
```sql
|
|
293
298
|
-- In an incremental model
|
|
@@ -295,8 +300,6 @@ your_profile:
|
|
|
295
300
|
prefer_single_alter_column=true) }}
|
|
296
301
|
```
|
|
297
302
|
|
|
298
|
-
**Compatibility notes:** Enabling `dbt_sqlserver_use_dbt_transactions: true` may expose transaction-state assumptions hidden by autocommit-only mode. Explicit transaction macros may interact with dbt-managed transactions, and cleanup after failed DDL/DML may differ. Review pre/post hooks for in-transaction vs out-of-transaction semantics.
|
|
299
|
-
|
|
300
303
|
### `as_columnstore`
|
|
301
304
|
|
|
302
305
|
*(default: `true`)* When building a table, the adapter creates a [clustered columnstore index](https://learn.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-overview) (CCI) on it. Set `as_columnstore: false` to build a plain rowstore table instead.
|
|
@@ -322,6 +325,10 @@ You can also set it per model:
|
|
|
322
325
|
|
|
323
326
|
With `table_refresh_method: dml`, a schema change makes the refresh fall back to a rename-swap. On that run — and only that run — the scratch table is rebuilt the way this adapter builds every other table, so it carries the model's columnstore index, and under an enforced contract its `NOT NULL`s and inline constraints, into the swap. That run therefore executes the model's SQL twice — once for the `SELECT … INTO` that probes for the schema change, once for the rebuild — and builds the columnstore index once. Steady-state refreshes are unaffected and keep the single `SELECT … INTO`. A table that lost its columnstore index to this bug before you upgraded is not repaired automatically: its schema still matches, so it stays on the cheap path. To rebuild it, temporarily set `full_refresh_build: prebuilt` and run with `--full-refresh`.
|
|
324
327
|
|
|
328
|
+
### Ephemeral models
|
|
329
|
+
|
|
330
|
+
Ephemeral models are supported, with one limit: an ephemeral model can't start with its own `WITH`. dbt inlines it as a CTE, and T-SQL can't nest a `WITH` inside one (still true on SQL Server 2025). Write it with derived tables instead, or materialize it as a `view`, which SQL Server expands into the calling query the same way.
|
|
331
|
+
|
|
325
332
|
### Constraints
|
|
326
333
|
|
|
327
334
|
Constraints declared in a model's yaml are applied when — and only when — the model's [contract](https://docs.getdbt.com/reference/resource-configs/contract) is enforced, which is what every dbt adapter does and keeps their cost opt-in. (dbt-core does not raise if you declare constraints with the contract off — they are simply never emitted.) `not_null`, `check`, `unique`, `primary_key` and `foreign_key` are all supported.
|
|
@@ -334,7 +341,7 @@ A *model-level* constraint carrying `name:` is applied by `ALTER TABLE … ADD C
|
|
|
334
341
|
|
|
335
342
|
Name a constraint when you want it stable across environments (schema-comparison tools report the generated names as differences) or need to reference it later. A `name:` on a *column-level* constraint is ignored with a warning — declare it under the model's `constraints:` key instead.
|
|
336
343
|
|
|
337
|
-
The full set of rules, with the test that verifies each, is in [docs/constraints.md](docs/constraints.md).
|
|
344
|
+
The full set of rules, with the test that verifies each, is in [docs/constraints.md](https://github.com/dbt-msft/dbt-sqlserver/blob/master/docs/constraints.md).
|
|
338
345
|
|
|
339
346
|
```yaml
|
|
340
347
|
models:
|
|
@@ -492,8 +499,8 @@ The `denies` config re-applies object-level DENYs after each build, diffed again
|
|
|
492
499
|
[](https://github.com/dbt-msft/dbt-sqlserver/actions/workflows/integration-tests-sqlserver.yml)
|
|
493
500
|
|
|
494
501
|
This adapter is community-maintained.
|
|
495
|
-
You are welcome to contribute by creating issues, opening or reviewing pull requests, or helping other users in the Slack
|
|
496
|
-
If you're unsure how to get started, check out our [contributing guide](CONTRIBUTING.md).
|
|
502
|
+
You are welcome to contribute by creating issues, opening or reviewing pull requests, or helping other users in [Discussions](https://github.com/dbt-msft/dbt-sqlserver/discussions) and on the [dbt Slack](https://getdbt.slack.com/archives/CMRMDDQ9W).
|
|
503
|
+
If you're unsure how to get started, check out our [contributing guide](https://github.com/dbt-msft/dbt-sqlserver/blob/master/CONTRIBUTING.md).
|
|
497
504
|
|
|
498
505
|
## License
|
|
499
506
|
|
|
@@ -60,6 +60,7 @@ dbt/include/sqlserver/macros/relations/table/clone.sql
|
|
|
60
60
|
dbt/include/sqlserver/macros/relations/table/create.sql
|
|
61
61
|
dbt/include/sqlserver/macros/relations/views/create.sql
|
|
62
62
|
dbt/include/sqlserver/macros/utils/any_value.sql
|
|
63
|
+
dbt/include/sqlserver/macros/utils/array_append.sql
|
|
63
64
|
dbt/include/sqlserver/macros/utils/array_construct.sql
|
|
64
65
|
dbt/include/sqlserver/macros/utils/cast_bool_to_text.sql
|
|
65
66
|
dbt/include/sqlserver/macros/utils/concat.sql
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version = "1.12.0rc4"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/relation_configs/__init__.py
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/relation_configs/index.py
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/relation_configs/policies.py
RENAMED
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_connections.py
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_constants.py
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_credentials.py
RENAMED
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_relation.py
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/adapters/sqlserver/sqlserver_runtime.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/catalog.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/indexes.sql
RENAMED
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/schema.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/adapters/show.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/any_value.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/concat.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/date_trunc.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/dateadd.sql
RENAMED
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/hash.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/last_day.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/length.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/listagg.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/openquery.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/position.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/safe_cast.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/split_part.sql
RENAMED
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt/include/sqlserver/macros/utils/timestamps.sql
RENAMED
|
File without changes
|
|
File without changes
|
{dbt_sqlserver-1.12.0rc4 → dbt_sqlserver-1.12.2}/dbt_sqlserver.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|