Compare commits

..

16 Commits

Author SHA1 Message Date
Jeremy Cohen
bb5c8669cc Experiment: markdown-output api docs 2023-01-11 11:33:00 +01:00
Michelle Ark
5b31cc4266 Remove UnsetProfileConfig (#6504)
remove UnsetProfileConfig
2023-01-06 20:12:40 -05:00
Chenyu Li
9bb1250869 merge main to feature/click-cli (#6483)
* merge main to feature/click-cli

* fix var hash

* move back changes in feature branch for deps

* fix logging issues
2023-01-06 15:11:23 -08:00
Michelle Ark
cc5a38ec5a Example click API usage (#6307)
* Example python lib w click, written docs

Co-authored-by: Chenyu Li <chenyu.li@dbtlabs.com>
2023-01-03 18:46:34 -05:00
Michelle Ark
b0909b8f5d Functional test framework working with Click, dbtRunner (#6387)
dbtRunner, dbt.cli.requires - preflight, profile, project
2022-12-16 19:54:42 -05:00
Stu Kilgore
5d278dacf1 Make clean task work with click (#6369) 2022-12-15 11:19:16 -06:00
Stu Kilgore
ce1aaec31d Adjust tox passenv to be multiline (#6405) (#6430) 2022-12-12 11:13:04 -06:00
Ian Knox
1809852a0d dbt run works with Click (#6396) 2022-12-08 09:47:08 -06:00
Ian Knox
88d2ee4813 Profile works w Click (#6336) 2022-12-08 09:38:15 -06:00
Stu Kilgore
77be2e4fdf Pin ubuntu at 20.04 for some workflows (#6380) 2022-12-05 10:55:36 -06:00
Michelle Ark
e91863de59 Set Flags from UserConfig (#6266)
flags with user config, flags.WHICH from invoked_subcommand if available
2022-12-02 15:23:58 -05:00
Michelle Ark
44b457c191 DepsTask with Click (#6260)
* deps with click, default --vars param, PartialProject.render_package_metadata
2022-11-22 17:52:59 -05:00
Chenyu Li
a0ec0b6f9d Project working with Click (#6142)
Co-authored-by: MichelleArk <michelle.ark@dbtlabs.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-11-15 15:54:05 -08:00
Ian Knox
1ec54abdc4 Logging works with Click (#6088) 2022-10-25 14:14:08 -05:00
Ian Knox
5efc4aa066 Fix CI issue with tox (#6137) 2022-10-25 13:32:15 -05:00
Chenyu Li
847c0b9644 Tracking works with Click (#5972)
Co-authored-by: Ian Knox <ian.knox@dbtlabs.com>
2022-10-25 10:41:57 -07:00
476 changed files with 41160 additions and 11507 deletions

View File

@@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 1.5.0a1 current_version = 1.4.0b1
parse = (?P<major>\d+) parse = (?P<major>\d+)
\.(?P<minor>\d+) \.(?P<minor>\d+)
\.(?P<patch>\d+) \.(?P<patch>\d+)

View File

@@ -3,7 +3,6 @@
For information on prior major and minor releases, see their changelogs: For information on prior major and minor releases, see their changelogs:
* [1.4](https://github.com/dbt-labs/dbt-core/blob/1.4.latest/CHANGELOG.md)
* [1.3](https://github.com/dbt-labs/dbt-core/blob/1.3.latest/CHANGELOG.md) * [1.3](https://github.com/dbt-labs/dbt-core/blob/1.3.latest/CHANGELOG.md)
* [1.2](https://github.com/dbt-labs/dbt-core/blob/1.2.latest/CHANGELOG.md) * [1.2](https://github.com/dbt-labs/dbt-core/blob/1.2.latest/CHANGELOG.md)
* [1.1](https://github.com/dbt-labs/dbt-core/blob/1.1.latest/CHANGELOG.md) * [1.1](https://github.com/dbt-labs/dbt-core/blob/1.1.latest/CHANGELOG.md)

89
.changes/1.4.0-b1.md Normal file
View File

@@ -0,0 +1,89 @@
## dbt-core 1.4.0-b1 - December 15, 2022
### Features
- Added favor-state flag to optionally favor state nodes even if unselected node exists ([#2968](https://github.com/dbt-labs/dbt-core/issues/2968))
- Update structured logging. Convert to using protobuf messages. Ensure events are enriched with node_info. ([#5610](https://github.com/dbt-labs/dbt-core/issues/5610))
- Friendlier error messages when packages.yml is malformed ([#5486](https://github.com/dbt-labs/dbt-core/issues/5486))
- Migrate dbt-utils current_timestamp macros into core + adapters ([#5521](https://github.com/dbt-labs/dbt-core/issues/5521))
- Allow partitions in external tables to be supplied as a list ([#5929](https://github.com/dbt-labs/dbt-core/issues/5929))
- extend -f flag shorthand for seed command ([#5990](https://github.com/dbt-labs/dbt-core/issues/5990))
- This pulls the profile name from args when constructing a RuntimeConfig in lib.py, enabling the dbt-server to override the value that's in the dbt_project.yml ([#6201](https://github.com/dbt-labs/dbt-core/issues/6201))
- Adding tarball install method for packages. Allowing package tarball to be specified via url in the packages.yaml. ([#4205](https://github.com/dbt-labs/dbt-core/issues/4205))
- Added an md5 function to the base context ([#6246](https://github.com/dbt-labs/dbt-core/issues/6246))
- Exposures support metrics in lineage ([#6057](https://github.com/dbt-labs/dbt-core/issues/6057))
- Add support for Python 3.11 ([#6147](https://github.com/dbt-labs/dbt-core/issues/6147))
- incremental predicates ([#5680](https://github.com/dbt-labs/dbt-core/issues/5680))
### Fixes
- Account for disabled flags on models in schema files more completely ([#3992](https://github.com/dbt-labs/dbt-core/issues/3992))
- Add validation of enabled config for metrics, exposures and sources ([#6030](https://github.com/dbt-labs/dbt-core/issues/6030))
- check length of args of python model function before accessing it ([#6041](https://github.com/dbt-labs/dbt-core/issues/6041))
- Add functors to ensure event types with str-type attributes are initialized to spec, even when provided non-str type params. ([#5436](https://github.com/dbt-labs/dbt-core/issues/5436))
- Allow hooks to fail without halting execution flow ([#5625](https://github.com/dbt-labs/dbt-core/issues/5625))
- Clarify Error Message for how many models are allowed in a Python file ([#6245](https://github.com/dbt-labs/dbt-core/issues/6245))
- After this, will be possible to use default values for dbt.config.get ([#6309](https://github.com/dbt-labs/dbt-core/issues/6309))
- Use full path for writing manifest ([#6055](https://github.com/dbt-labs/dbt-core/issues/6055))
- [CT-1284] Change Python model default materialization to table ([#6345](https://github.com/dbt-labs/dbt-core/issues/6345))
- Repair a regression which prevented basic logging before the logging subsystem is completely configured. ([#6434](https://github.com/dbt-labs/dbt-core/issues/6434))
### Docs
- minor doc correction ([dbt-docs/#5791](https://github.com/dbt-labs/dbt-docs/issues/5791))
- Generate API docs for new CLI interface ([dbt-docs/#5528](https://github.com/dbt-labs/dbt-docs/issues/5528))
- ([dbt-docs/#5880](https://github.com/dbt-labs/dbt-docs/issues/5880))
- Fix rendering of sample code for metrics ([dbt-docs/#323](https://github.com/dbt-labs/dbt-docs/issues/323))
- Alphabetize `core/dbt/README.md` ([dbt-docs/#6368](https://github.com/dbt-labs/dbt-docs/issues/6368))
### Under the Hood
- Put black config in explicit config ([#5946](https://github.com/dbt-labs/dbt-core/issues/5946))
- Added flat_graph attribute the Manifest class's deepcopy() coverage ([#5809](https://github.com/dbt-labs/dbt-core/issues/5809))
- Add mypy configs so `mypy` passes from CLI ([#5983](https://github.com/dbt-labs/dbt-core/issues/5983))
- Exception message cleanup. ([#6023](https://github.com/dbt-labs/dbt-core/issues/6023))
- Add dmypy cache to gitignore ([#6028](https://github.com/dbt-labs/dbt-core/issues/6028))
- Provide useful errors when the value of 'materialized' is invalid ([#5229](https://github.com/dbt-labs/dbt-core/issues/5229))
- Clean up string formatting ([#6068](https://github.com/dbt-labs/dbt-core/issues/6068))
- Fixed extra whitespace in strings introduced by black. ([#1350](https://github.com/dbt-labs/dbt-core/issues/1350))
- Remove the 'root_path' field from most nodes ([#6171](https://github.com/dbt-labs/dbt-core/issues/6171))
- Combine certain logging events with different levels ([#6173](https://github.com/dbt-labs/dbt-core/issues/6173))
- Convert threading tests to pytest ([#5942](https://github.com/dbt-labs/dbt-core/issues/5942))
- Convert postgres index tests to pytest ([#5770](https://github.com/dbt-labs/dbt-core/issues/5770))
- Convert use color tests to pytest ([#5771](https://github.com/dbt-labs/dbt-core/issues/5771))
- Add github actions workflow to generate high level CLI API docs ([#5942](https://github.com/dbt-labs/dbt-core/issues/5942))
- Functionality-neutral refactor of event logging system to improve encapsulation and modularity. ([#6139](https://github.com/dbt-labs/dbt-core/issues/6139))
- Consolidate ParsedNode and CompiledNode classes ([#6383](https://github.com/dbt-labs/dbt-core/issues/6383))
- Prevent doc gen workflow from running on forks ([#6386](https://github.com/dbt-labs/dbt-core/issues/6386))
- Fix intermittent database connection failure in Windows CI test ([#6394](https://github.com/dbt-labs/dbt-core/issues/6394))
- Refactor and clean up manifest nodes ([#6426](https://github.com/dbt-labs/dbt-core/issues/6426))
- Restore important legacy logging behaviors, following refactor which removed them ([#6437](https://github.com/dbt-labs/dbt-core/issues/6437))
### Dependencies
- Update pathspec requirement from ~=0.9.0 to >=0.9,<0.11 in /core ([#5917](https://github.com/dbt-labs/dbt-core/pull/5917))
- Bump black from 22.8.0 to 22.10.0 ([#6019](https://github.com/dbt-labs/dbt-core/pull/6019))
- Bump mashumaro[msgpack] from 3.0.4 to 3.1.1 in /core ([#6108](https://github.com/dbt-labs/dbt-core/pull/6108))
- Update colorama requirement from <0.4.6,>=0.3.9 to >=0.3.9,<0.4.7 in /core ([#6144](https://github.com/dbt-labs/dbt-core/pull/6144))
- Bump mashumaro[msgpack] from 3.1.1 to 3.2 in /core ([#4904](https://github.com/dbt-labs/dbt-core/issues/4904))
### Contributors
- [@andy-clapson](https://github.com/andy-clapson) ([dbt-docs/#5791](https://github.com/dbt-labs/dbt-docs/issues/5791))
- [@chamini2](https://github.com/chamini2) ([#6041](https://github.com/dbt-labs/dbt-core/issues/6041))
- [@daniel-murray](https://github.com/daniel-murray) ([#2968](https://github.com/dbt-labs/dbt-core/issues/2968))
- [@dave-connors-3](https://github.com/dave-connors-3) ([#5990](https://github.com/dbt-labs/dbt-core/issues/5990))
- [@dbeatty10](https://github.com/dbeatty10) ([dbt-docs/#6368](https://github.com/dbt-labs/dbt-docs/issues/6368), [#6394](https://github.com/dbt-labs/dbt-core/issues/6394))
- [@devmessias](https://github.com/devmessias) ([#6309](https://github.com/dbt-labs/dbt-core/issues/6309))
- [@eve-johns](https://github.com/eve-johns) ([#6068](https://github.com/dbt-labs/dbt-core/issues/6068))
- [@haritamar](https://github.com/haritamar) ([#6246](https://github.com/dbt-labs/dbt-core/issues/6246))
- [@jared-rimmer](https://github.com/jared-rimmer) ([#5486](https://github.com/dbt-labs/dbt-core/issues/5486))
- [@josephberni](https://github.com/josephberni) ([#2968](https://github.com/dbt-labs/dbt-core/issues/2968))
- [@joshuataylor](https://github.com/joshuataylor) ([#6147](https://github.com/dbt-labs/dbt-core/issues/6147))
- [@justbldwn](https://github.com/justbldwn) ([#6245](https://github.com/dbt-labs/dbt-core/issues/6245))
- [@luke-bassett](https://github.com/luke-bassett) ([#1350](https://github.com/dbt-labs/dbt-core/issues/1350))
- [@max-sixty](https://github.com/max-sixty) ([#5946](https://github.com/dbt-labs/dbt-core/issues/5946), [#5983](https://github.com/dbt-labs/dbt-core/issues/5983), [#6028](https://github.com/dbt-labs/dbt-core/issues/6028))
- [@paulbenschmidt](https://github.com/paulbenschmidt) ([dbt-docs/#5880](https://github.com/dbt-labs/dbt-docs/issues/5880))
- [@pgoslatara](https://github.com/pgoslatara) ([#5929](https://github.com/dbt-labs/dbt-core/issues/5929))
- [@racheldaniel](https://github.com/racheldaniel) ([#6201](https://github.com/dbt-labs/dbt-core/issues/6201))
- [@timle2](https://github.com/timle2) ([#4205](https://github.com/dbt-labs/dbt-core/issues/4205))
- [@dave-connors-3](https://github.com/dave-connors-3) ([#5680](https://github.com/dbt-labs/dbt-core/issues/5680))

View File

@@ -0,0 +1,6 @@
kind: "Dependencies"
body: "Update pathspec requirement from ~=0.9.0 to >=0.9,<0.11 in /core"
time: 2022-09-23T00:06:46.00000Z
custom:
Author: dependabot[bot]
PR: "5917"

View File

@@ -0,0 +1,6 @@
kind: "Dependencies"
body: "Bump black from 22.8.0 to 22.10.0"
time: 2022-10-07T00:08:48.00000Z
custom:
Author: dependabot[bot]
PR: "6019"

View File

@@ -0,0 +1,6 @@
kind: "Dependencies"
body: "Bump mashumaro[msgpack] from 3.0.4 to 3.1.1 in /core"
time: 2022-10-20T00:07:53.00000Z
custom:
Author: dependabot[bot]
PR: "6108"

View File

@@ -0,0 +1,6 @@
kind: "Dependencies"
body: "Update colorama requirement from <0.4.6,>=0.3.9 to >=0.3.9,<0.4.7 in /core"
time: 2022-10-26T00:09:10.00000Z
custom:
Author: dependabot[bot]
PR: "6144"

View File

@@ -0,0 +1,7 @@
kind: "Dependencies"
body: "Bump mashumaro[msgpack] from 3.1.1 to 3.2 in /core"
time: 2022-12-05T00:21:18.00000Z
custom:
Author: dependabot[bot]
Issue: 4904
PR: 6375

View File

@@ -0,0 +1,6 @@
kind: Docs
body: minor doc correction
time: 2022-09-08T15:41:57.689162-04:00
custom:
Author: andy-clapson
Issue: "5791"

View File

@@ -0,0 +1,6 @@
kind: Docs
body: Generate API docs for new CLI interface
time: 2022-10-07T09:06:56.446078-05:00
custom:
Author: stu-k
Issue: "5528"

View File

@@ -0,0 +1,5 @@
kind: Docs
time: 2022-10-17T17:14:11.715348-05:00
custom:
Author: paulbenschmidt
Issue: "5880"

View File

@@ -0,0 +1,6 @@
kind: Docs
body: Fix rendering of sample code for metrics
time: 2022-11-16T15:57:43.204201+01:00
custom:
Author: jtcohen6
Issue: "323"

View File

@@ -0,0 +1,6 @@
kind: Docs
body: Alphabetize `core/dbt/README.md`
time: 2022-12-02T15:05:23.695333-07:00
custom:
Author: dbeatty10
Issue: "6368"

View File

@@ -0,0 +1,7 @@
kind: Features
body: Added favor-state flag to optionally favor state nodes even if unselected node
exists
time: 2022-04-08T16:54:59.696564+01:00
custom:
Author: daniel-murray josephberni
Issue: "2968"

View File

@@ -0,0 +1,6 @@
kind: Features
body: Update structured logging. Convert to using protobuf messages. Ensure events are enriched with node_info.
time: 2022-08-17T15:48:57.225267-04:00
custom:
Author: gshank
Issue: "5610"

View File

@@ -0,0 +1,7 @@
kind: Features
body: incremental predicates
time: 2022-08-23T08:57:27.640804-05:00
custom:
Author: dave-connors-3
Issue: "5680"
PR: "5702"

View File

@@ -0,0 +1,6 @@
kind: Features
body: Friendlier error messages when packages.yml is malformed
time: 2022-09-12T12:59:35.121188+01:00
custom:
Author: jared-rimmer
Issue: "5486"

View File

@@ -0,0 +1,6 @@
kind: Features
body: Migrate dbt-utils current_timestamp macros into core + adapters
time: 2022-09-14T09:56:25.97818-07:00
custom:
Author: colin-rogers-dbt
Issue: "5521"

View File

@@ -0,0 +1,6 @@
kind: Features
body: Allow partitions in external tables to be supplied as a list
time: 2022-09-25T21:16:51.051239654+02:00
custom:
Author: pgoslatara
Issue: "5929"

View File

@@ -0,0 +1,6 @@
kind: Features
body: extend -f flag shorthand for seed command
time: 2022-10-03T11:07:05.381632-05:00
custom:
Author: dave-connors-3
Issue: "5990"

View File

@@ -0,0 +1,7 @@
kind: Features
body: This pulls the profile name from args when constructing a RuntimeConfig in lib.py,
enabling the dbt-server to override the value that's in the dbt_project.yml
time: 2022-11-02T15:00:03.000805-05:00
custom:
Author: racheldaniel
Issue: "6201"

View File

@@ -0,0 +1,8 @@
kind: Features
body: Adding tarball install method for packages. Allowing package tarball to be specified
via url in the packages.yaml.
time: 2022-11-07T10:50:18.464545-05:00
custom:
Author: timle2
Issue: "4205"
PR: "4689"

View File

@@ -0,0 +1,6 @@
kind: Features
body: Added an md5 function to the base context
time: 2022-11-14T18:52:07.788593+02:00
custom:
Author: haritamar
Issue: "6246"

View File

@@ -0,0 +1,6 @@
kind: Features
body: Exposures support metrics in lineage
time: 2022-11-30T11:29:13.256034-05:00
custom:
Author: michelleark
Issue: "6057"

View File

@@ -0,0 +1,7 @@
kind: Features
body: Add support for Python 3.11
time: 2022-12-06T15:07:04.753127+01:00
custom:
Author: joshuataylor MichelleArk jtcohen6
Issue: "6147"
PR: "6326"

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: Account for disabled flags on models in schema files more completely
time: 2022-09-16T10:48:54.162273-05:00
custom:
Author: emmyoop
Issue: "3992"

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: Add validation of enabled config for metrics, exposures and sources
time: 2022-10-10T11:32:18.752322-05:00
custom:
Author: emmyoop
Issue: "6030"

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: check length of args of python model function before accessing it
time: 2022-10-11T16:07:15.464093-04:00
custom:
Author: chamini2
Issue: "6041"

View File

@@ -0,0 +1,7 @@
kind: Fixes
body: Add functors to ensure event types with str-type attributes are initialized
to spec, even when provided non-str type params.
time: 2022-10-16T17:37:42.846683-07:00
custom:
Author: versusfacit
Issue: "5436"

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: Allow hooks to fail without halting execution flow
time: 2022-11-07T09:53:14.340257-06:00
custom:
Author: ChenyuLInx
Issue: "5625"

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: Clarify Error Message for how many models are allowed in a Python file
time: 2022-11-15T08:10:21.527884-05:00
custom:
Author: justbldwn
Issue: "6245"

View File

@@ -0,0 +1,7 @@
kind: Fixes
body: After this, will be possible to use default values for dbt.config.get
time: 2022-11-24T16:34:19.039512764-03:00
custom:
Author: devmessias
Issue: "6309"
PR: "6317"

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: Use full path for writing manifest
time: 2022-12-02T16:48:59.029519-05:00
custom:
Author: gshank
Issue: "6055"

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: '[CT-1284] Change Python model default materialization to table'
time: 2022-12-13T11:26:20.550017-08:00
custom:
Author: aranke
Issue: "6345"

View File

@@ -0,0 +1,7 @@
kind: Fixes
body: Repair a regression which prevented basic logging before the logging subsystem
is completely configured.
time: 2022-12-14T15:53:07.396512-05:00
custom:
Author: peterallenwebb
Issue: "6434"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Put black config in explicit config
time: 2022-09-27T19:42:59.241433-07:00
custom:
Author: max-sixty
Issue: "5946"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Added flat_graph attribute the Manifest class's deepcopy() coverage
time: 2022-09-29T13:44:06.275941-04:00
custom:
Author: peterallenwebb
Issue: "5809"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Add mypy configs so `mypy` passes from CLI
time: 2022-10-05T12:03:10.061263-07:00
custom:
Author: max-sixty
Issue: "5983"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Exception message cleanup.
time: 2022-10-07T09:46:27.682872-05:00
custom:
Author: emmyoop
Issue: "6023"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Add dmypy cache to gitignore
time: 2022-10-07T14:00:44.227644-07:00
custom:
Author: max-sixty
Issue: "6028"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Provide useful errors when the value of 'materialized' is invalid
time: 2022-10-13T18:19:12.167548-04:00
custom:
Author: peterallenwebb
Issue: "5229"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Fixed extra whitespace in strings introduced by black.
time: 2022-10-17T15:15:11.499246-05:00
custom:
Author: luke-bassett
Issue: "1350"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Clean up string formatting
time: 2022-10-17T15:58:44.676549-04:00
custom:
Author: eve-johns
Issue: "6068"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Remove the 'root_path' field from most nodes
time: 2022-10-28T10:48:37.687886-04:00
custom:
Author: gshank
Issue: "6171"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Combine certain logging events with different levels
time: 2022-10-28T11:03:44.887836-04:00
custom:
Author: gshank
Issue: "6173"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Convert threading tests to pytest
time: 2022-11-08T07:45:50.589147-06:00
custom:
Author: stu-k
Issue: "5942"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Convert postgres index tests to pytest
time: 2022-11-08T11:56:33.743042-06:00
custom:
Author: stu-k
Issue: "5770"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Convert use color tests to pytest
time: 2022-11-08T13:31:04.788547-06:00
custom:
Author: stu-k
Issue: "5771"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Add github actions workflow to generate high level CLI API docs
time: 2022-11-16T13:00:37.916202-06:00
custom:
Author: stu-k
Issue: "5942"

View File

@@ -0,0 +1,8 @@
kind: Under the Hood
body: Functionality-neutral refactor of event logging system to improve encapsulation
and modularity.
time: 2022-11-18T14:57:17.792622-05:00
custom:
Author: peterallenwebb
Issue: "6139"
PR: "6291"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Consolidate ParsedNode and CompiledNode classes
time: 2022-12-05T16:49:48.563583-05:00
custom:
Author: gshank
Issue: "6383"
PR: "6384"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Prevent doc gen workflow from running on forks
time: 2022-12-06T09:40:15.301984-06:00
custom:
Author: stu-k
Issue: "6386"
PR: "6390"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Fix intermittent database connection failure in Windows CI test
time: 2022-12-06T11:30:53.166009-07:00
custom:
Author: MichelleArk dbeatty10
Issue: "6394"
PR: "6395"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Refactor and clean up manifest nodes
time: 2022-12-11T21:42:40.560074-05:00
custom:
Author: gshank
Issue: "6426"
PR: "6427"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Restore important legacy logging behaviors, following refactor which removed
them
time: 2022-12-13T21:41:06.815133-05:00
custom:
Author: peterallenwebb
Issue: "6437"

View File

@@ -0,0 +1,9 @@
kind: Breaking Changes
body: Cleaned up exceptions to directly raise in code. Removed use of all exception
functions in the code base and marked them all as deprecated to be removed next
minor release.
time: 2022-12-05T14:19:37.863032-06:00
custom:
Author: emmyoop
Issue: "6339"
PR: "6347"

View File

@@ -0,0 +1,7 @@
kind: Features
body: Click CLI Flags work with UserConfig
time: 2022-11-29T18:32:39.068035-05:00
custom:
Author: michelleark
Issue: "6327"
PR: "6266"

View File

@@ -1,6 +0,0 @@
kind: Features
body: Adding the entity node
time: 2023-01-18T13:48:04.487817-06:00
custom:
Author: callum-mcdata
Issue: "6627"

View File

@@ -0,0 +1,8 @@
kind: Fixes
body: Add functors to ensure event types with str-type attributes are initialized
to spec, even when provided non-str type params.
time: 2022-10-16T17:37:42.846683-07:00
custom:
Author: versusfacit
Issue: "5436"
PR: "5874"

View File

@@ -0,0 +1,7 @@
kind: Fixes
body: Fix typo in util.py
time: 2022-11-17T22:03:20.4836855+09:00
custom:
Author: eltociear
Issue: "4904"
PR: "6037"

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: '[CT-1591] Don''t parse empty Python files'
time: 2022-12-13T11:39:15.818464-08:00
custom:
Author: aranke
Issue: "6345"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Fixed extra whitespace in strings introduced by black.
time: 2022-10-17T15:15:11.499246-05:00
custom:
Author: luke-bassett
Issue: "1350"
PR: "6086"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Clean up string formatting
time: 2022-10-17T15:58:44.676549-04:00
custom:
Author: eve-johns
Issue: "6068"
PR: "6082"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Click CLI supports logging
time: 2022-10-17T17:05:00.478948-05:00
custom:
Author: iknox-fa
Issue: "5530"
PR: "6088"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: '`dbt clean` works with click cli'
time: 2022-12-02T12:30:46.711184-06:00
custom:
Author: stu-k
Issue: "5542"
PR: "6369"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Adds Profile support to the new Click CLI
time: 2022-12-04T16:11:10.417872-06:00
custom:
Author: iknox-fa ChenyuLInx
Issue: "5536"
PR: "6336"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Pin ubuntu at 20.04 for some workflows
time: 2022-12-05T09:22:17.614875-06:00
custom:
Author: stu-k
Issue: "9999"
PR: "6380"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: '`dbt run` works with Click cli'
time: 2022-12-06T15:17:59.765623-06:00
custom:
Author: iknox-fa
Issue: "5551"
PR: "6396"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Cherry pick tox fix
time: 2022-12-12T11:08:59.440276-06:00
custom:
Author: stu-k
Issue: "9999"
PR: "6430"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: functional tests run using click cli through dbtRunner
time: 2022-12-14T11:20:48.521869-05:00
custom:
Author: MichelleArk
Issue: "6096"
PR: "6387"

View File

@@ -0,0 +1,6 @@
kind: Under the Hood
body: Treat dense text blobs as binary for `git grep`
time: 2022-12-19T19:34:35.890275-07:00
custom:
Author: dbeatty10
Issue: "6294"

View File

@@ -0,0 +1,7 @@
kind: Under the Hood
body: Remove UnsetProfileConfig
time: 2023-01-05T10:47:48.707656-05:00
custom:
Author: MichelleArk
Issue: "5539"
PR: "6504"

View File

@@ -1,6 +0,0 @@
kind: Under the Hood
body: Fix use of ConnectionReused logging event
time: 2023-01-13T13:25:13.023168-05:00
custom:
Author: gshank
Issue: "6168"

View File

@@ -1,6 +0,0 @@
kind: Under the Hood
body: Update deprecated github action command
time: 2023-01-17T11:17:37.046095-06:00
custom:
Author: davidbloss
Issue: "6153"

View File

@@ -9,4 +9,4 @@ ignore =
E203 # makes Flake8 work like black E203 # makes Flake8 work like black
E741 E741
E501 # long line checking is done in black E501 # long line checking is done in black
exclude = test/ exclude = test

20
.github/_README.md vendored
View File

@@ -63,12 +63,12 @@ permissions:
contents: read contents: read
pull-requests: write pull-requests: write
``` ```
### Secrets ### Secrets
- When to use a [Personal Access Token (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) vs the [GITHUB_TOKEN](https://docs.github.com/en/actions/security-guides/automatic-token-authentication) generated for the action? - When to use a [Personal Access Token (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) vs the [GITHUB_TOKEN](https://docs.github.com/en/actions/security-guides/automatic-token-authentication) generated for the action?
The `GITHUB_TOKEN` is used by default. In most cases it is sufficient for what you need. The `GITHUB_TOKEN` is used by default. In most cases it is sufficient for what you need.
If you expect the workflow to result in a commit to that should retrigger workflows, you will need to use a Personal Access Token for the bot to commit the file. When using the GITHUB_TOKEN, the resulting commit will not trigger another GitHub Actions Workflow run. This is due to limitations set by GitHub. See [the docs](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow) for a more detailed explanation. If you expect the workflow to result in a commit to that should retrigger workflows, you will need to use a Personal Access Token for the bot to commit the file. When using the GITHUB_TOKEN, the resulting commit will not trigger another GitHub Actions Workflow run. This is due to limitations set by GitHub. See [the docs](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow) for a more detailed explanation.
For example, we must use a PAT in our workflow to commit a new changelog yaml file for bot PRs. Once the file has been committed to the branch, it should retrigger the check to validate that a changelog exists on the PR. Otherwise, it would stay in a failed state since the check would never retrigger. For example, we must use a PAT in our workflow to commit a new changelog yaml file for bot PRs. Once the file has been committed to the branch, it should retrigger the check to validate that a changelog exists on the PR. Otherwise, it would stay in a failed state since the check would never retrigger.
@@ -105,7 +105,7 @@ Some triggers of note that we use:
``` ```
# **what?** # **what?**
# Describe what the action does. # Describe what the action does.
# **why?** # **why?**
# Why does this action exist? # Why does this action exist?
@@ -138,7 +138,7 @@ Some triggers of note that we use:
id: fp id: fp
run: | run: |
FILEPATH=.changes/unreleased/Dependencies-${{ steps.filename_time.outputs.time }}.yaml FILEPATH=.changes/unreleased/Dependencies-${{ steps.filename_time.outputs.time }}.yaml
echo "FILEPATH=$FILEPATH" >> $GITHUB_OUTPUT echo "::set-output name=FILEPATH::$FILEPATH"
``` ```
- Print out all variables you will reference as the first step of a job. This allows for easier debugging. The first job should log all inputs. Subsequent jobs should reference outputs of other jobs, if present. - Print out all variables you will reference as the first step of a job. This allows for easier debugging. The first job should log all inputs. Subsequent jobs should reference outputs of other jobs, if present.
@@ -158,14 +158,14 @@ Some triggers of note that we use:
echo "The build_script_path: ${{ inputs.build_script_path }}" echo "The build_script_path: ${{ inputs.build_script_path }}"
echo "The s3_bucket_name: ${{ inputs.s3_bucket_name }}" echo "The s3_bucket_name: ${{ inputs.s3_bucket_name }}"
echo "The package_test_command: ${{ inputs.package_test_command }}" echo "The package_test_command: ${{ inputs.package_test_command }}"
# collect all the variables that need to be used in subsequent jobs # collect all the variables that need to be used in subsequent jobs
- name: Set Variables - name: Set Variables
id: variables id: variables
run: | run: |
echo "important_path='performance/runner/Cargo.toml'" >> $GITHUB_OUTPUT echo "::set-output name=important_path::'performance/runner/Cargo.toml'"
echo "release_id=${{github.event.inputs.release_id}}" >> $GITHUB_OUTPUT echo "::set-output name=release_id::${{github.event.inputs.release_id}}"
echo "open_prs=${{github.event.inputs.open_prs}}" >> $GITHUB_OUTPUT echo "::set-output name=open_prs::${{github.event.inputs.open_prs}}"
job2: job2:
needs: [job1] needs: [job1]
@@ -190,7 +190,7 @@ ___
### Actions from the Marketplace ### Actions from the Marketplace
- Dont use external actions for things that can easily be accomplished manually. - Dont use external actions for things that can easily be accomplished manually.
- Always read through what an external action does before using it! Often an action in the GitHub Actions Marketplace can be replaced with a few lines in bash. This is much more maintainable (and wont change under us) and clear as to whats actually happening. It also prevents any - Always read through what an external action does before using it! Often an action in the GitHub Actions Marketplace can be replaced with a few lines in bash. This is much more maintainable (and wont change under us) and clear as to whats actually happening. It also prevents any
- Pin actions _we don't control_ to tags. - Pin actions _we don't control_ to tags.
### Connecting to AWS ### Connecting to AWS
- Authenticate with the aws managed workflow - Authenticate with the aws managed workflow
@@ -208,7 +208,7 @@ ___
```yaml ```yaml
- name: Copy Artifacts from S3 via CLI - name: Copy Artifacts from S3 via CLI
run: aws s3 cp ${{ env.s3_bucket }} . --recursive run: aws s3 cp ${{ env.s3_bucket }} . --recursive
``` ```
### Testing ### Testing

View File

@@ -28,12 +28,11 @@ if __name__ == "__main__":
if package_request.status_code == 404: if package_request.status_code == 404:
if halt_on_missing: if halt_on_missing:
sys.exit(1) sys.exit(1)
# everything is the latest if the package doesn't exist else:
github_output = os.environ.get("GITHUB_OUTPUT") # everything is the latest if the package doesn't exist
with open(github_output, "at", encoding="utf-8") as gh_output: print(f"::set-output name=latest::{True}")
gh_output.write("latest=True") print(f"::set-output name=minor_latest::{True}")
gh_output.write("minor_latest=True") sys.exit(0)
sys.exit(0)
# TODO: verify package meta is "correct" # TODO: verify package meta is "correct"
# https://github.com/dbt-labs/dbt-core/issues/4640 # https://github.com/dbt-labs/dbt-core/issues/4640
@@ -92,7 +91,5 @@ if __name__ == "__main__":
latest = is_latest(pre_rel, new_version, current_latest) latest = is_latest(pre_rel, new_version, current_latest)
minor_latest = is_latest(pre_rel, new_version, current_minor_latest) minor_latest = is_latest(pre_rel, new_version, current_minor_latest)
github_output = os.environ.get("GITHUB_OUTPUT") print(f"::set-output name=latest::{latest}")
with open(github_output, "at", encoding="utf-8") as gh_output: print(f"::set-output name=minor_latest::{minor_latest}")
gh_output.write(f"latest={latest}")
gh_output.write(f"minor_latest={minor_latest}")

View File

@@ -145,6 +145,7 @@ jobs:
echo "creating docs" echo "creating docs"
make html make html
make markdown
- name: debug - name: debug
run: | run: |

View File

@@ -101,9 +101,7 @@ jobs:
- name: Get current date - name: Get current date
if: always() if: always()
id: date id: date
run: | run: echo "::set-output name=date::$(date +'%Y-%m-%dT%H_%M_%S')" #no colons allowed for artifacts
CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts
echo "date=$CURRENT_DATE" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
if: always() if: always()
@@ -170,9 +168,7 @@ jobs:
- name: Get current date - name: Get current date
if: always() if: always()
id: date id: date
run: | run: echo "::set-output name=date::$(date +'%Y_%m_%dT%H_%M_%S')" #no colons allowed for artifacts
CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts
echo "date=$CURRENT_DATE" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
if: always() if: always()

View File

@@ -41,9 +41,9 @@ jobs:
id: version id: version
run: | run: |
IFS="." read -r MAJOR MINOR PATCH <<< ${{ github.event.inputs.version_number }} IFS="." read -r MAJOR MINOR PATCH <<< ${{ github.event.inputs.version_number }}
echo "major=$MAJOR" >> $GITHUB_OUTPUT echo "::set-output name=major::$MAJOR"
echo "minor=$MINOR" >> $GITHUB_OUTPUT echo "::set-output name=minor::$MINOR"
echo "patch=$PATCH" >> $GITHUB_OUTPUT echo "::set-output name=patch::$PATCH"
- name: Is pkg 'latest' - name: Is pkg 'latest'
id: latest id: latest
@@ -70,10 +70,8 @@ jobs:
- name: Get docker build arg - name: Get docker build arg
id: build_arg id: build_arg
run: | run: |
BUILD_ARG_NAME=$(echo ${{ github.event.inputs.package }} | sed 's/\-/_/g') echo "::set-output name=build_arg_name::"$(echo ${{ github.event.inputs.package }} | sed 's/\-/_/g')
BUILD_ARG_VALUE=$(echo ${{ github.event.inputs.package }} | sed 's/postgres/core/g') echo "::set-output name=build_arg_value::"$(echo ${{ github.event.inputs.package }} | sed 's/postgres/core/g')
echo "build_arg_name=$BUILD_ARG_NAME" >> $GITHUB_OUTPUT
echo "build_arg_value=$BUILD_ARG_VALUE" >> $GITHUB_OUTPUT
- name: Log in to the GHCR - name: Log in to the GHCR
uses: docker/login-action@v1 uses: docker/login-action@v1

View File

@@ -165,7 +165,7 @@ jobs:
env: env:
IS_PRERELEASE: ${{ contains(github.event.inputs.version_number, 'rc') || contains(github.event.inputs.version_number, 'b') }} IS_PRERELEASE: ${{ contains(github.event.inputs.version_number, 'rc') || contains(github.event.inputs.version_number, 'b') }}
run: | run: |
echo "isPrerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT echo ::set-output name=isPrerelease::$IS_PRERELEASE
- name: Creating GitHub Release - name: Creating GitHub Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1

View File

@@ -65,7 +65,7 @@ jobs:
- name: Set branch value - name: Set branch value
id: variables id: variables
run: | run: |
echo "BRANCH_NAME=prep-release/${{ github.event.inputs.version_number }}_$GITHUB_RUN_ID" >> $GITHUB_OUTPUT echo "::set-output name=BRANCH_NAME::prep-release/${{ github.event.inputs.version_number }}_$GITHUB_RUN_ID"
- name: Create PR branch - name: Create PR branch
run: | run: |

View File

@@ -5,12 +5,102 @@
- "Breaking changes" listed under a version may require action from end users or external maintainers when upgrading to that version. - "Breaking changes" listed under a version may require action from end users or external maintainers when upgrading to that version.
- Do not edit this file directly. This file is auto-generated using [changie](https://github.com/miniscruff/changie). For details on how to document a change, see [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md#adding-changelog-entry) - Do not edit this file directly. This file is auto-generated using [changie](https://github.com/miniscruff/changie). For details on how to document a change, see [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md#adding-changelog-entry)
## dbt-core 1.4.0-b1 - December 15, 2022
### Features
- Added favor-state flag to optionally favor state nodes even if unselected node exists ([#2968](https://github.com/dbt-labs/dbt-core/issues/2968))
- Update structured logging. Convert to using protobuf messages. Ensure events are enriched with node_info. ([#5610](https://github.com/dbt-labs/dbt-core/issues/5610))
- Friendlier error messages when packages.yml is malformed ([#5486](https://github.com/dbt-labs/dbt-core/issues/5486))
- Migrate dbt-utils current_timestamp macros into core + adapters ([#5521](https://github.com/dbt-labs/dbt-core/issues/5521))
- Allow partitions in external tables to be supplied as a list ([#5929](https://github.com/dbt-labs/dbt-core/issues/5929))
- extend -f flag shorthand for seed command ([#5990](https://github.com/dbt-labs/dbt-core/issues/5990))
- This pulls the profile name from args when constructing a RuntimeConfig in lib.py, enabling the dbt-server to override the value that's in the dbt_project.yml ([#6201](https://github.com/dbt-labs/dbt-core/issues/6201))
- Adding tarball install method for packages. Allowing package tarball to be specified via url in the packages.yaml. ([#4205](https://github.com/dbt-labs/dbt-core/issues/4205))
- Added an md5 function to the base context ([#6246](https://github.com/dbt-labs/dbt-core/issues/6246))
- Exposures support metrics in lineage ([#6057](https://github.com/dbt-labs/dbt-core/issues/6057))
- Add support for Python 3.11 ([#6147](https://github.com/dbt-labs/dbt-core/issues/6147))
- incremental predicates ([#5680](https://github.com/dbt-labs/dbt-core/issues/5680))
### Fixes
- Account for disabled flags on models in schema files more completely ([#3992](https://github.com/dbt-labs/dbt-core/issues/3992))
- Add validation of enabled config for metrics, exposures and sources ([#6030](https://github.com/dbt-labs/dbt-core/issues/6030))
- check length of args of python model function before accessing it ([#6041](https://github.com/dbt-labs/dbt-core/issues/6041))
- Add functors to ensure event types with str-type attributes are initialized to spec, even when provided non-str type params. ([#5436](https://github.com/dbt-labs/dbt-core/issues/5436))
- Allow hooks to fail without halting execution flow ([#5625](https://github.com/dbt-labs/dbt-core/issues/5625))
- Clarify Error Message for how many models are allowed in a Python file ([#6245](https://github.com/dbt-labs/dbt-core/issues/6245))
- After this, will be possible to use default values for dbt.config.get ([#6309](https://github.com/dbt-labs/dbt-core/issues/6309))
- Use full path for writing manifest ([#6055](https://github.com/dbt-labs/dbt-core/issues/6055))
- [CT-1284] Change Python model default materialization to table ([#6345](https://github.com/dbt-labs/dbt-core/issues/6345))
- Repair a regression which prevented basic logging before the logging subsystem is completely configured. ([#6434](https://github.com/dbt-labs/dbt-core/issues/6434))
### Docs
- minor doc correction ([dbt-docs/#5791](https://github.com/dbt-labs/dbt-docs/issues/5791))
- Generate API docs for new CLI interface ([dbt-docs/#5528](https://github.com/dbt-labs/dbt-docs/issues/5528))
- ([dbt-docs/#5880](https://github.com/dbt-labs/dbt-docs/issues/5880))
- Fix rendering of sample code for metrics ([dbt-docs/#323](https://github.com/dbt-labs/dbt-docs/issues/323))
- Alphabetize `core/dbt/README.md` ([dbt-docs/#6368](https://github.com/dbt-labs/dbt-docs/issues/6368))
### Under the Hood
- Put black config in explicit config ([#5946](https://github.com/dbt-labs/dbt-core/issues/5946))
- Added flat_graph attribute the Manifest class's deepcopy() coverage ([#5809](https://github.com/dbt-labs/dbt-core/issues/5809))
- Add mypy configs so `mypy` passes from CLI ([#5983](https://github.com/dbt-labs/dbt-core/issues/5983))
- Exception message cleanup. ([#6023](https://github.com/dbt-labs/dbt-core/issues/6023))
- Add dmypy cache to gitignore ([#6028](https://github.com/dbt-labs/dbt-core/issues/6028))
- Provide useful errors when the value of 'materialized' is invalid ([#5229](https://github.com/dbt-labs/dbt-core/issues/5229))
- Clean up string formatting ([#6068](https://github.com/dbt-labs/dbt-core/issues/6068))
- Fixed extra whitespace in strings introduced by black. ([#1350](https://github.com/dbt-labs/dbt-core/issues/1350))
- Remove the 'root_path' field from most nodes ([#6171](https://github.com/dbt-labs/dbt-core/issues/6171))
- Combine certain logging events with different levels ([#6173](https://github.com/dbt-labs/dbt-core/issues/6173))
- Convert threading tests to pytest ([#5942](https://github.com/dbt-labs/dbt-core/issues/5942))
- Convert postgres index tests to pytest ([#5770](https://github.com/dbt-labs/dbt-core/issues/5770))
- Convert use color tests to pytest ([#5771](https://github.com/dbt-labs/dbt-core/issues/5771))
- Add github actions workflow to generate high level CLI API docs ([#5942](https://github.com/dbt-labs/dbt-core/issues/5942))
- Functionality-neutral refactor of event logging system to improve encapsulation and modularity. ([#6139](https://github.com/dbt-labs/dbt-core/issues/6139))
- Consolidate ParsedNode and CompiledNode classes ([#6383](https://github.com/dbt-labs/dbt-core/issues/6383))
- Prevent doc gen workflow from running on forks ([#6386](https://github.com/dbt-labs/dbt-core/issues/6386))
- Fix intermittent database connection failure in Windows CI test ([#6394](https://github.com/dbt-labs/dbt-core/issues/6394))
- Refactor and clean up manifest nodes ([#6426](https://github.com/dbt-labs/dbt-core/issues/6426))
- Restore important legacy logging behaviors, following refactor which removed them ([#6437](https://github.com/dbt-labs/dbt-core/issues/6437))
### Dependencies
- Update pathspec requirement from ~=0.9.0 to >=0.9,<0.11 in /core ([#5917](https://github.com/dbt-labs/dbt-core/pull/5917))
- Bump black from 22.8.0 to 22.10.0 ([#6019](https://github.com/dbt-labs/dbt-core/pull/6019))
- Bump mashumaro[msgpack] from 3.0.4 to 3.1.1 in /core ([#6108](https://github.com/dbt-labs/dbt-core/pull/6108))
- Update colorama requirement from <0.4.6,>=0.3.9 to >=0.3.9,<0.4.7 in /core ([#6144](https://github.com/dbt-labs/dbt-core/pull/6144))
- Bump mashumaro[msgpack] from 3.1.1 to 3.2 in /core ([#4904](https://github.com/dbt-labs/dbt-core/issues/4904))
### Contributors
- [@andy-clapson](https://github.com/andy-clapson) ([dbt-docs/#5791](https://github.com/dbt-labs/dbt-docs/issues/5791))
- [@chamini2](https://github.com/chamini2) ([#6041](https://github.com/dbt-labs/dbt-core/issues/6041))
- [@daniel-murray](https://github.com/daniel-murray) ([#2968](https://github.com/dbt-labs/dbt-core/issues/2968))
- [@dave-connors-3](https://github.com/dave-connors-3) ([#5990](https://github.com/dbt-labs/dbt-core/issues/5990))
- [@dbeatty10](https://github.com/dbeatty10) ([dbt-docs/#6368](https://github.com/dbt-labs/dbt-docs/issues/6368), [#6394](https://github.com/dbt-labs/dbt-core/issues/6394))
- [@devmessias](https://github.com/devmessias) ([#6309](https://github.com/dbt-labs/dbt-core/issues/6309))
- [@eve-johns](https://github.com/eve-johns) ([#6068](https://github.com/dbt-labs/dbt-core/issues/6068))
- [@haritamar](https://github.com/haritamar) ([#6246](https://github.com/dbt-labs/dbt-core/issues/6246))
- [@jared-rimmer](https://github.com/jared-rimmer) ([#5486](https://github.com/dbt-labs/dbt-core/issues/5486))
- [@josephberni](https://github.com/josephberni) ([#2968](https://github.com/dbt-labs/dbt-core/issues/2968))
- [@joshuataylor](https://github.com/joshuataylor) ([#6147](https://github.com/dbt-labs/dbt-core/issues/6147))
- [@justbldwn](https://github.com/justbldwn) ([#6245](https://github.com/dbt-labs/dbt-core/issues/6245))
- [@luke-bassett](https://github.com/luke-bassett) ([#1350](https://github.com/dbt-labs/dbt-core/issues/1350))
- [@max-sixty](https://github.com/max-sixty) ([#5946](https://github.com/dbt-labs/dbt-core/issues/5946), [#5983](https://github.com/dbt-labs/dbt-core/issues/5983), [#6028](https://github.com/dbt-labs/dbt-core/issues/6028))
- [@paulbenschmidt](https://github.com/paulbenschmidt) ([dbt-docs/#5880](https://github.com/dbt-labs/dbt-docs/issues/5880))
- [@pgoslatara](https://github.com/pgoslatara) ([#5929](https://github.com/dbt-labs/dbt-core/issues/5929))
- [@racheldaniel](https://github.com/racheldaniel) ([#6201](https://github.com/dbt-labs/dbt-core/issues/6201))
- [@timle2](https://github.com/timle2) ([#4205](https://github.com/dbt-labs/dbt-core/issues/4205))
- [@dave-connors-3](https://github.com/dave-connors-3) ([#5680](https://github.com/dbt-labs/dbt-core/issues/5680))
## Previous Releases ## Previous Releases
For information on prior major and minor releases, see their changelogs: For information on prior major and minor releases, see their changelogs:
* [1.4](https://github.com/dbt-labs/dbt-core/blob/1.4.latest/CHANGELOG.md)
* [1.3](https://github.com/dbt-labs/dbt-core/blob/1.3.latest/CHANGELOG.md) * [1.3](https://github.com/dbt-labs/dbt-core/blob/1.3.latest/CHANGELOG.md)
* [1.2](https://github.com/dbt-labs/dbt-core/blob/1.2.latest/CHANGELOG.md) * [1.2](https://github.com/dbt-labs/dbt-core/blob/1.2.latest/CHANGELOG.md)
* [1.1](https://github.com/dbt-labs/dbt-core/blob/1.1.latest/CHANGELOG.md) * [1.1](https://github.com/dbt-labs/dbt-core/blob/1.1.latest/CHANGELOG.md)

View File

@@ -96,15 +96,12 @@ brew install postgresql
### Installation ### Installation
First make sure that you set up your `virtualenv` as described in [Setting up an environment](#setting-up-an-environment). Also ensure you have the latest version of pip installed with `pip install --upgrade pip`. Next, install `dbt-core` (and its dependencies): First make sure that you set up your `virtualenv` as described in [Setting up an environment](#setting-up-an-environment). Also ensure you have the latest version of pip installed with `pip install --upgrade pip`. Next, install `dbt-core` (and its dependencies) with:
```sh ```sh
make dev make dev
``` # or
or, alternatively:
```sh
pip install -r dev-requirements.txt -r editable-requirements.txt pip install -r dev-requirements.txt -r editable-requirements.txt
pre-commit install
``` ```
When installed in this way, any changes you make to your local copy of the source code will be reflected immediately in your next `dbt` run. When installed in this way, any changes you make to your local copy of the source code will be reflected immediately in your next `dbt` run.

View File

@@ -19,16 +19,11 @@ CI_FLAGS =\
LOG_DIR=./logs\ LOG_DIR=./logs\
DBT_LOG_FORMAT=json DBT_LOG_FORMAT=json
.PHONY: dev_req .PHONY: dev
dev_req: ## Installs dbt-* packages in develop mode along with only development dependencies. dev: ## Installs dbt-* packages in develop mode along with development dependencies.
@\ @\
pip install -r dev-requirements.txt -r editable-requirements.txt pip install -r dev-requirements.txt -r editable-requirements.txt
.PHONY: dev
dev: dev_req ## Installs dbt-* packages in develop mode along with development dependencies and pre-commit.
@\
pre-commit install
.PHONY: mypy .PHONY: mypy
mypy: .env ## Runs mypy against staged changes for static type checking. mypy: .env ## Runs mypy against staged changes for static type checking.
@\ @\

View File

@@ -2,7 +2,7 @@ from dataclasses import dataclass
import re import re
from typing import Dict, ClassVar, Any, Optional from typing import Dict, ClassVar, Any, Optional
from dbt.exceptions import DbtRuntimeError from dbt.exceptions import RuntimeException
@dataclass @dataclass
@@ -85,7 +85,7 @@ class Column:
def string_size(self) -> int: def string_size(self) -> int:
if not self.is_string(): if not self.is_string():
raise DbtRuntimeError("Called string_size() on non-string field!") raise RuntimeException("Called string_size() on non-string field!")
if self.dtype == "text" or self.char_size is None: if self.dtype == "text" or self.char_size is None:
# char_size should never be None. Handle it reasonably just in case # char_size should never be None. Handle it reasonably just in case
@@ -124,7 +124,7 @@ class Column:
def from_description(cls, name: str, raw_data_type: str) -> "Column": def from_description(cls, name: str, raw_data_type: str) -> "Column":
match = re.match(r"([^(]+)(\([^)]+\))?", raw_data_type) match = re.match(r"([^(]+)(\([^)]+\))?", raw_data_type)
if match is None: if match is None:
raise DbtRuntimeError(f'Could not interpret data type "{raw_data_type}"') raise RuntimeException(f'Could not interpret data type "{raw_data_type}"')
data_type, size_info = match.groups() data_type, size_info = match.groups()
char_size = None char_size = None
numeric_precision = None numeric_precision = None
@@ -137,7 +137,7 @@ class Column:
try: try:
char_size = int(parts[0]) char_size = int(parts[0])
except ValueError: except ValueError:
raise DbtRuntimeError( raise RuntimeException(
f'Could not interpret data_type "{raw_data_type}": ' f'Could not interpret data_type "{raw_data_type}": '
f'could not convert "{parts[0]}" to an integer' f'could not convert "{parts[0]}" to an integer'
) )
@@ -145,14 +145,14 @@ class Column:
try: try:
numeric_precision = int(parts[0]) numeric_precision = int(parts[0])
except ValueError: except ValueError:
raise DbtRuntimeError( raise RuntimeException(
f'Could not interpret data_type "{raw_data_type}": ' f'Could not interpret data_type "{raw_data_type}": '
f'could not convert "{parts[0]}" to an integer' f'could not convert "{parts[0]}" to an integer'
) )
try: try:
numeric_scale = int(parts[1]) numeric_scale = int(parts[1])
except ValueError: except ValueError:
raise DbtRuntimeError( raise RuntimeException(
f'Could not interpret data_type "{raw_data_type}": ' f'Could not interpret data_type "{raw_data_type}": '
f'could not convert "{parts[1]}" to an integer' f'could not convert "{parts[1]}" to an integer'
) )

View File

@@ -91,13 +91,13 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
key = self.get_thread_identifier() key = self.get_thread_identifier()
with self.lock: with self.lock:
if key not in self.thread_connections: if key not in self.thread_connections:
raise dbt.exceptions.InvalidConnectionError(key, list(self.thread_connections)) raise dbt.exceptions.InvalidConnectionException(key, list(self.thread_connections))
return self.thread_connections[key] return self.thread_connections[key]
def set_thread_connection(self, conn: Connection) -> None: def set_thread_connection(self, conn: Connection) -> None:
key = self.get_thread_identifier() key = self.get_thread_identifier()
if key in self.thread_connections: if key in self.thread_connections:
raise dbt.exceptions.DbtInternalError( raise dbt.exceptions.InternalException(
"In set_thread_connection, existing connection exists for {}" "In set_thread_connection, existing connection exists for {}"
) )
self.thread_connections[key] = conn self.thread_connections[key] = conn
@@ -137,49 +137,49 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
:return: A context manager that handles exceptions raised by the :return: A context manager that handles exceptions raised by the
underlying database. underlying database.
""" """
raise dbt.exceptions.NotImplementedError( raise dbt.exceptions.NotImplementedException(
"`exception_handler` is not implemented for this adapter!" "`exception_handler` is not implemented for this adapter!"
) )
def set_connection_name(self, name: Optional[str] = None) -> Connection: def set_connection_name(self, name: Optional[str] = None) -> Connection:
"""Called by 'acquire_connection' in BaseAdapter, which is called by conn_name: str
'connection_named', called by 'connection_for(node)'. if name is None:
Creates a connection for this thread if one doesn't already # if a name isn't specified, we'll re-use a single handle
exist, and will rename an existing connection.""" # named 'master'
conn_name = "master"
else:
if not isinstance(name, str):
raise dbt.exceptions.CompilerException(
f"For connection name, got {name} - not a string!"
)
assert isinstance(name, str)
conn_name = name
conn_name: str = "master" if name is None else name
# Get a connection for this thread
conn = self.get_if_exists() conn = self.get_if_exists()
if conn and conn.name == conn_name and conn.state == "open":
# Found a connection and nothing to do, so just return it
return conn
if conn is None: if conn is None:
# Create a new connection
conn = Connection( conn = Connection(
type=Identifier(self.TYPE), type=Identifier(self.TYPE),
name=conn_name, name=None,
state=ConnectionState.INIT, state=ConnectionState.INIT,
transaction_open=False, transaction_open=False,
handle=None, handle=None,
credentials=self.profile.credentials, credentials=self.profile.credentials,
) )
conn.handle = LazyHandle(self.open)
# Add the connection to thread_connections for this thread
self.set_thread_connection(conn) self.set_thread_connection(conn)
fire_event(
NewConnection(conn_name=conn_name, conn_type=self.TYPE, node_info=get_node_info())
)
else: # existing connection either wasn't open or didn't have the right name
if conn.state != "open":
conn.handle = LazyHandle(self.open)
if conn.name != conn_name:
orig_conn_name: str = conn.name or ""
conn.name = conn_name
fire_event(ConnectionReused(orig_conn_name=orig_conn_name, conn_name=conn_name))
if conn.name == conn_name and conn.state == "open":
return conn
fire_event(
NewConnection(conn_name=conn_name, conn_type=self.TYPE, node_info=get_node_info())
)
if conn.state == "open":
fire_event(ConnectionReused(conn_name=conn_name))
else:
conn.handle = LazyHandle(self.open)
conn.name = conn_name
return conn return conn
@classmethod @classmethod
@@ -211,7 +211,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
connect should trigger a retry. connect should trigger a retry.
:type retryable_exceptions: Iterable[Type[Exception]] :type retryable_exceptions: Iterable[Type[Exception]]
:param int retry_limit: How many times to retry the call to connect. If this limit :param int retry_limit: How many times to retry the call to connect. If this limit
is exceeded before a successful call, a FailedToConnectError will be raised. is exceeded before a successful call, a FailedToConnectException will be raised.
Must be non-negative. Must be non-negative.
:param retry_timeout: Time to wait between attempts to connect. Can also take a :param retry_timeout: Time to wait between attempts to connect. Can also take a
Callable that takes the number of attempts so far, beginning at 0, and returns an int Callable that takes the number of attempts so far, beginning at 0, and returns an int
@@ -220,14 +220,14 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
:param int _attempts: Parameter used to keep track of the number of attempts in calling the :param int _attempts: Parameter used to keep track of the number of attempts in calling the
connect function across recursive calls. Passed as an argument to retry_timeout if it connect function across recursive calls. Passed as an argument to retry_timeout if it
is a Callable. This parameter should not be set by the initial caller. is a Callable. This parameter should not be set by the initial caller.
:raises dbt.exceptions.FailedToConnectError: Upon exhausting all retry attempts without :raises dbt.exceptions.FailedToConnectException: Upon exhausting all retry attempts without
successfully acquiring a handle. successfully acquiring a handle.
:return: The given connection with its appropriate state and handle attributes set :return: The given connection with its appropriate state and handle attributes set
depending on whether we successfully acquired a handle or not. depending on whether we successfully acquired a handle or not.
""" """
timeout = retry_timeout(_attempts) if callable(retry_timeout) else retry_timeout timeout = retry_timeout(_attempts) if callable(retry_timeout) else retry_timeout
if timeout < 0: if timeout < 0:
raise dbt.exceptions.FailedToConnectError( raise dbt.exceptions.FailedToConnectException(
"retry_timeout cannot be negative or return a negative time." "retry_timeout cannot be negative or return a negative time."
) )
@@ -235,7 +235,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
# This guard is not perfect others may add to the recursion limit (e.g. built-ins). # This guard is not perfect others may add to the recursion limit (e.g. built-ins).
connection.handle = None connection.handle = None
connection.state = ConnectionState.FAIL connection.state = ConnectionState.FAIL
raise dbt.exceptions.FailedToConnectError("retry_limit cannot be negative") raise dbt.exceptions.FailedToConnectException("retry_limit cannot be negative")
try: try:
connection.handle = connect() connection.handle = connect()
@@ -246,7 +246,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
if retry_limit <= 0: if retry_limit <= 0:
connection.handle = None connection.handle = None
connection.state = ConnectionState.FAIL connection.state = ConnectionState.FAIL
raise dbt.exceptions.FailedToConnectError(str(e)) raise dbt.exceptions.FailedToConnectException(str(e))
logger.debug( logger.debug(
f"Got a retryable error when attempting to open a {cls.TYPE} connection.\n" f"Got a retryable error when attempting to open a {cls.TYPE} connection.\n"
@@ -268,12 +268,12 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
except Exception as e: except Exception as e:
connection.handle = None connection.handle = None
connection.state = ConnectionState.FAIL connection.state = ConnectionState.FAIL
raise dbt.exceptions.FailedToConnectError(str(e)) raise dbt.exceptions.FailedToConnectException(str(e))
@abc.abstractmethod @abc.abstractmethod
def cancel_open(self) -> Optional[List[str]]: def cancel_open(self) -> Optional[List[str]]:
"""Cancel all open connections on the adapter. (passable)""" """Cancel all open connections on the adapter. (passable)"""
raise dbt.exceptions.NotImplementedError( raise dbt.exceptions.NotImplementedException(
"`cancel_open` is not implemented for this adapter!" "`cancel_open` is not implemented for this adapter!"
) )
@@ -288,7 +288,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
This should be thread-safe, or hold the lock if necessary. The given This should be thread-safe, or hold the lock if necessary. The given
connection should not be in either in_use or available. connection should not be in either in_use or available.
""" """
raise dbt.exceptions.NotImplementedError("`open` is not implemented for this adapter!") raise dbt.exceptions.NotImplementedException("`open` is not implemented for this adapter!")
def release(self) -> None: def release(self) -> None:
with self.lock: with self.lock:
@@ -320,12 +320,16 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
@abc.abstractmethod @abc.abstractmethod
def begin(self) -> None: def begin(self) -> None:
"""Begin a transaction. (passable)""" """Begin a transaction. (passable)"""
raise dbt.exceptions.NotImplementedError("`begin` is not implemented for this adapter!") raise dbt.exceptions.NotImplementedException(
"`begin` is not implemented for this adapter!"
)
@abc.abstractmethod @abc.abstractmethod
def commit(self) -> None: def commit(self) -> None:
"""Commit a transaction. (passable)""" """Commit a transaction. (passable)"""
raise dbt.exceptions.NotImplementedError("`commit` is not implemented for this adapter!") raise dbt.exceptions.NotImplementedException(
"`commit` is not implemented for this adapter!"
)
@classmethod @classmethod
def _rollback_handle(cls, connection: Connection) -> None: def _rollback_handle(cls, connection: Connection) -> None:
@@ -361,7 +365,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
def _rollback(cls, connection: Connection) -> None: def _rollback(cls, connection: Connection) -> None:
"""Roll back the given connection.""" """Roll back the given connection."""
if connection.transaction_open is False: if connection.transaction_open is False:
raise dbt.exceptions.DbtInternalError( raise dbt.exceptions.InternalException(
f"Tried to rollback transaction on connection " f"Tried to rollback transaction on connection "
f'"{connection.name}", but it does not have one open!' f'"{connection.name}", but it does not have one open!'
) )
@@ -411,4 +415,6 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
:return: A tuple of the query status and results (empty if fetch=False). :return: A tuple of the query status and results (empty if fetch=False).
:rtype: Tuple[AdapterResponse, agate.Table] :rtype: Tuple[AdapterResponse, agate.Table]
""" """
raise dbt.exceptions.NotImplementedError("`execute` is not implemented for this adapter!") raise dbt.exceptions.NotImplementedException(
"`execute` is not implemented for this adapter!"
)

View File

@@ -22,20 +22,20 @@ import agate
import pytz import pytz
from dbt.exceptions import ( from dbt.exceptions import (
DbtInternalError, InternalException,
MacroArgTypeError, InvalidMacroArgType,
MacroResultError, InvalidMacroResult,
QuoteConfigTypeError, InvalidQuoteConfigType,
NotImplementedError, NotImplementedException,
NullRelationCacheAttemptedError, NullRelationCacheAttempted,
NullRelationDropAttemptedError, NullRelationDropAttempted,
RelationReturnedMultipleResultsError, RelationReturnedMultipleResults,
RenameToNoneAttemptedError, RenameToNoneAttempted,
DbtRuntimeError, RuntimeException,
SnapshotTargetIncompleteError, SnapshotTargetIncomplete,
SnapshotTargetNotSnapshotTableError, SnapshotTargetNotSnapshotTable,
UnexpectedNullError, UnexpectedNull,
UnexpectedNonTimestampError, UnexpectedNonTimestamp,
) )
from dbt.adapters.protocol import ( from dbt.adapters.protocol import (
@@ -75,7 +75,7 @@ FRESHNESS_MACRO_NAME = "collect_freshness"
def _expect_row_value(key: str, row: agate.Row): def _expect_row_value(key: str, row: agate.Row):
if key not in row.keys(): if key not in row.keys():
raise DbtInternalError( raise InternalException(
'Got a row without "{}" column, columns: {}'.format(key, row.keys()) 'Got a row without "{}" column, columns: {}'.format(key, row.keys())
) )
return row[key] return row[key]
@@ -104,10 +104,10 @@ def _utc(dt: Optional[datetime], source: BaseRelation, field_name: str) -> datet
assume the datetime is already for UTC and add the timezone. assume the datetime is already for UTC and add the timezone.
""" """
if dt is None: if dt is None:
raise UnexpectedNullError(field_name, source) raise UnexpectedNull(field_name, source)
elif not hasattr(dt, "tzinfo"): elif not hasattr(dt, "tzinfo"):
raise UnexpectedNonTimestampError(field_name, source, dt) raise UnexpectedNonTimestamp(field_name, source, dt)
elif dt.tzinfo: elif dt.tzinfo:
return dt.astimezone(pytz.UTC) return dt.astimezone(pytz.UTC)
@@ -433,7 +433,7 @@ class BaseAdapter(metaclass=AdapterMeta):
"""Cache a new relation in dbt. It will show up in `list relations`.""" """Cache a new relation in dbt. It will show up in `list relations`."""
if relation is None: if relation is None:
name = self.nice_connection_name() name = self.nice_connection_name()
raise NullRelationCacheAttemptedError(name) raise NullRelationCacheAttempted(name)
self.cache.add(relation) self.cache.add(relation)
# so jinja doesn't render things # so jinja doesn't render things
return "" return ""
@@ -445,7 +445,7 @@ class BaseAdapter(metaclass=AdapterMeta):
""" """
if relation is None: if relation is None:
name = self.nice_connection_name() name = self.nice_connection_name()
raise NullRelationDropAttemptedError(name) raise NullRelationDropAttempted(name)
self.cache.drop(relation) self.cache.drop(relation)
return "" return ""
@@ -462,7 +462,7 @@ class BaseAdapter(metaclass=AdapterMeta):
name = self.nice_connection_name() name = self.nice_connection_name()
src_name = _relation_name(from_relation) src_name = _relation_name(from_relation)
dst_name = _relation_name(to_relation) dst_name = _relation_name(to_relation)
raise RenameToNoneAttemptedError(src_name, dst_name, name) raise RenameToNoneAttempted(src_name, dst_name, name)
self.cache.rename(from_relation, to_relation) self.cache.rename(from_relation, to_relation)
return "" return ""
@@ -474,12 +474,12 @@ class BaseAdapter(metaclass=AdapterMeta):
@abc.abstractmethod @abc.abstractmethod
def date_function(cls) -> str: def date_function(cls) -> str:
"""Get the date function used by this adapter's database.""" """Get the date function used by this adapter's database."""
raise NotImplementedError("`date_function` is not implemented for this adapter!") raise NotImplementedException("`date_function` is not implemented for this adapter!")
@classmethod @classmethod
@abc.abstractmethod @abc.abstractmethod
def is_cancelable(cls) -> bool: def is_cancelable(cls) -> bool:
raise NotImplementedError("`is_cancelable` is not implemented for this adapter!") raise NotImplementedException("`is_cancelable` is not implemented for this adapter!")
### ###
# Abstract methods about schemas # Abstract methods about schemas
@@ -487,7 +487,7 @@ class BaseAdapter(metaclass=AdapterMeta):
@abc.abstractmethod @abc.abstractmethod
def list_schemas(self, database: str) -> List[str]: def list_schemas(self, database: str) -> List[str]:
"""Get a list of existing schemas in database""" """Get a list of existing schemas in database"""
raise NotImplementedError("`list_schemas` is not implemented for this adapter!") raise NotImplementedException("`list_schemas` is not implemented for this adapter!")
@available.parse(lambda *a, **k: False) @available.parse(lambda *a, **k: False)
def check_schema_exists(self, database: str, schema: str) -> bool: def check_schema_exists(self, database: str, schema: str) -> bool:
@@ -510,13 +510,13 @@ class BaseAdapter(metaclass=AdapterMeta):
*Implementors must call self.cache.drop() to preserve cache state!* *Implementors must call self.cache.drop() to preserve cache state!*
""" """
raise NotImplementedError("`drop_relation` is not implemented for this adapter!") raise NotImplementedException("`drop_relation` is not implemented for this adapter!")
@abc.abstractmethod @abc.abstractmethod
@available.parse_none @available.parse_none
def truncate_relation(self, relation: BaseRelation) -> None: def truncate_relation(self, relation: BaseRelation) -> None:
"""Truncate the given relation.""" """Truncate the given relation."""
raise NotImplementedError("`truncate_relation` is not implemented for this adapter!") raise NotImplementedException("`truncate_relation` is not implemented for this adapter!")
@abc.abstractmethod @abc.abstractmethod
@available.parse_none @available.parse_none
@@ -525,13 +525,15 @@ class BaseAdapter(metaclass=AdapterMeta):
Implementors must call self.cache.rename() to preserve cache state. Implementors must call self.cache.rename() to preserve cache state.
""" """
raise NotImplementedError("`rename_relation` is not implemented for this adapter!") raise NotImplementedException("`rename_relation` is not implemented for this adapter!")
@abc.abstractmethod @abc.abstractmethod
@available.parse_list @available.parse_list
def get_columns_in_relation(self, relation: BaseRelation) -> List[BaseColumn]: def get_columns_in_relation(self, relation: BaseRelation) -> List[BaseColumn]:
"""Get a list of the columns in the given Relation.""" """Get a list of the columns in the given Relation."""
raise NotImplementedError("`get_columns_in_relation` is not implemented for this adapter!") raise NotImplementedException(
"`get_columns_in_relation` is not implemented for this adapter!"
)
@available.deprecated("get_columns_in_relation", lambda *a, **k: []) @available.deprecated("get_columns_in_relation", lambda *a, **k: [])
def get_columns_in_table(self, schema: str, identifier: str) -> List[BaseColumn]: def get_columns_in_table(self, schema: str, identifier: str) -> List[BaseColumn]:
@@ -553,7 +555,7 @@ class BaseAdapter(metaclass=AdapterMeta):
:param self.Relation current: A relation that currently exists in the :param self.Relation current: A relation that currently exists in the
database with columns of unspecified types. database with columns of unspecified types.
""" """
raise NotImplementedError( raise NotImplementedException(
"`expand_target_column_types` is not implemented for this adapter!" "`expand_target_column_types` is not implemented for this adapter!"
) )
@@ -568,7 +570,7 @@ class BaseAdapter(metaclass=AdapterMeta):
:return: The relations in schema :return: The relations in schema
:rtype: List[self.Relation] :rtype: List[self.Relation]
""" """
raise NotImplementedError( raise NotImplementedException(
"`list_relations_without_caching` is not implemented for this adapter!" "`list_relations_without_caching` is not implemented for this adapter!"
) )
@@ -610,7 +612,7 @@ class BaseAdapter(metaclass=AdapterMeta):
to_relation. to_relation.
""" """
if not isinstance(from_relation, self.Relation): if not isinstance(from_relation, self.Relation):
raise MacroArgTypeError( raise InvalidMacroArgType(
method_name="get_missing_columns", method_name="get_missing_columns",
arg_name="from_relation", arg_name="from_relation",
got_value=from_relation, got_value=from_relation,
@@ -618,7 +620,7 @@ class BaseAdapter(metaclass=AdapterMeta):
) )
if not isinstance(to_relation, self.Relation): if not isinstance(to_relation, self.Relation):
raise MacroArgTypeError( raise InvalidMacroArgType(
method_name="get_missing_columns", method_name="get_missing_columns",
arg_name="to_relation", arg_name="to_relation",
got_value=to_relation, got_value=to_relation,
@@ -639,11 +641,11 @@ class BaseAdapter(metaclass=AdapterMeta):
expected columns. expected columns.
:param Relation relation: The relation to check :param Relation relation: The relation to check
:raises InvalidMacroArgType: If the columns are :raises CompilationException: If the columns are
incorrect. incorrect.
""" """
if not isinstance(relation, self.Relation): if not isinstance(relation, self.Relation):
raise MacroArgTypeError( raise InvalidMacroArgType(
method_name="valid_snapshot_target", method_name="valid_snapshot_target",
arg_name="relation", arg_name="relation",
got_value=relation, got_value=relation,
@@ -664,16 +666,16 @@ class BaseAdapter(metaclass=AdapterMeta):
if missing: if missing:
if extra: if extra:
raise SnapshotTargetIncompleteError(extra, missing) raise SnapshotTargetIncomplete(extra, missing)
else: else:
raise SnapshotTargetNotSnapshotTableError(missing) raise SnapshotTargetNotSnapshotTable(missing)
@available.parse_none @available.parse_none
def expand_target_column_types( def expand_target_column_types(
self, from_relation: BaseRelation, to_relation: BaseRelation self, from_relation: BaseRelation, to_relation: BaseRelation
) -> None: ) -> None:
if not isinstance(from_relation, self.Relation): if not isinstance(from_relation, self.Relation):
raise MacroArgTypeError( raise InvalidMacroArgType(
method_name="expand_target_column_types", method_name="expand_target_column_types",
arg_name="from_relation", arg_name="from_relation",
got_value=from_relation, got_value=from_relation,
@@ -681,7 +683,7 @@ class BaseAdapter(metaclass=AdapterMeta):
) )
if not isinstance(to_relation, self.Relation): if not isinstance(to_relation, self.Relation):
raise MacroArgTypeError( raise InvalidMacroArgType(
method_name="expand_target_column_types", method_name="expand_target_column_types",
arg_name="to_relation", arg_name="to_relation",
got_value=to_relation, got_value=to_relation,
@@ -763,7 +765,7 @@ class BaseAdapter(metaclass=AdapterMeta):
"schema": schema, "schema": schema,
"database": database, "database": database,
} }
raise RelationReturnedMultipleResultsError(kwargs, matches) raise RelationReturnedMultipleResults(kwargs, matches)
elif matches: elif matches:
return matches[0] return matches[0]
@@ -785,20 +787,20 @@ class BaseAdapter(metaclass=AdapterMeta):
@available.parse_none @available.parse_none
def create_schema(self, relation: BaseRelation): def create_schema(self, relation: BaseRelation):
"""Create the given schema if it does not exist.""" """Create the given schema if it does not exist."""
raise NotImplementedError("`create_schema` is not implemented for this adapter!") raise NotImplementedException("`create_schema` is not implemented for this adapter!")
@abc.abstractmethod @abc.abstractmethod
@available.parse_none @available.parse_none
def drop_schema(self, relation: BaseRelation): def drop_schema(self, relation: BaseRelation):
"""Drop the given schema (and everything in it) if it exists.""" """Drop the given schema (and everything in it) if it exists."""
raise NotImplementedError("`drop_schema` is not implemented for this adapter!") raise NotImplementedException("`drop_schema` is not implemented for this adapter!")
@available @available
@classmethod @classmethod
@abc.abstractmethod @abc.abstractmethod
def quote(cls, identifier: str) -> str: def quote(cls, identifier: str) -> str:
"""Quote the given identifier, as appropriate for the database.""" """Quote the given identifier, as appropriate for the database."""
raise NotImplementedError("`quote` is not implemented for this adapter!") raise NotImplementedException("`quote` is not implemented for this adapter!")
@available @available
def quote_as_configured(self, identifier: str, quote_key: str) -> str: def quote_as_configured(self, identifier: str, quote_key: str) -> str:
@@ -827,7 +829,7 @@ class BaseAdapter(metaclass=AdapterMeta):
elif quote_config is None: elif quote_config is None:
pass pass
else: else:
raise QuoteConfigTypeError(quote_config) raise InvalidQuoteConfigType(quote_config)
if quote_columns: if quote_columns:
return self.quote(column) return self.quote(column)
@@ -848,7 +850,7 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column. :param col_idx: The index into the agate table for the column.
:return: The name of the type in the database :return: The name of the type in the database
""" """
raise NotImplementedError("`convert_text_type` is not implemented for this adapter!") raise NotImplementedException("`convert_text_type` is not implemented for this adapter!")
@classmethod @classmethod
@abc.abstractmethod @abc.abstractmethod
@@ -860,7 +862,7 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column. :param col_idx: The index into the agate table for the column.
:return: The name of the type in the database :return: The name of the type in the database
""" """
raise NotImplementedError("`convert_number_type` is not implemented for this adapter!") raise NotImplementedException("`convert_number_type` is not implemented for this adapter!")
@classmethod @classmethod
@abc.abstractmethod @abc.abstractmethod
@@ -872,7 +874,9 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column. :param col_idx: The index into the agate table for the column.
:return: The name of the type in the database :return: The name of the type in the database
""" """
raise NotImplementedError("`convert_boolean_type` is not implemented for this adapter!") raise NotImplementedException(
"`convert_boolean_type` is not implemented for this adapter!"
)
@classmethod @classmethod
@abc.abstractmethod @abc.abstractmethod
@@ -884,7 +888,9 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column. :param col_idx: The index into the agate table for the column.
:return: The name of the type in the database :return: The name of the type in the database
""" """
raise NotImplementedError("`convert_datetime_type` is not implemented for this adapter!") raise NotImplementedException(
"`convert_datetime_type` is not implemented for this adapter!"
)
@classmethod @classmethod
@abc.abstractmethod @abc.abstractmethod
@@ -896,7 +902,7 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column. :param col_idx: The index into the agate table for the column.
:return: The name of the type in the database :return: The name of the type in the database
""" """
raise NotImplementedError("`convert_date_type` is not implemented for this adapter!") raise NotImplementedException("`convert_date_type` is not implemented for this adapter!")
@classmethod @classmethod
@abc.abstractmethod @abc.abstractmethod
@@ -908,7 +914,7 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column. :param col_idx: The index into the agate table for the column.
:return: The name of the type in the database :return: The name of the type in the database
""" """
raise NotImplementedError("`convert_time_type` is not implemented for this adapter!") raise NotImplementedException("`convert_time_type` is not implemented for this adapter!")
@available @available
@classmethod @classmethod
@@ -975,7 +981,7 @@ class BaseAdapter(metaclass=AdapterMeta):
else: else:
package_name = 'the "{}" package'.format(project) package_name = 'the "{}" package'.format(project)
raise DbtRuntimeError( raise RuntimeException(
'dbt could not find a macro with the name "{}" in {}'.format( 'dbt could not find a macro with the name "{}" in {}'.format(
macro_name, package_name macro_name, package_name
) )
@@ -1073,7 +1079,7 @@ class BaseAdapter(metaclass=AdapterMeta):
# now we have a 1-row table of the maximum `loaded_at_field` value and # now we have a 1-row table of the maximum `loaded_at_field` value and
# the current time according to the db. # the current time according to the db.
if len(table) != 1 or len(table[0]) != 2: if len(table) != 1 or len(table[0]) != 2:
raise MacroResultError(FRESHNESS_MACRO_NAME, table) raise InvalidMacroResult(FRESHNESS_MACRO_NAME, table)
if table[0][0] is None: if table[0][0] is None:
# no records in the table, so really the max_loaded_at was # no records in the table, so really the max_loaded_at was
# infinitely long ago. Just call it 0:00 January 1 year UTC # infinitely long ago. Just call it 0:00 January 1 year UTC
@@ -1150,7 +1156,7 @@ class BaseAdapter(metaclass=AdapterMeta):
elif location == "prepend": elif location == "prepend":
return f"'{value}' || {add_to}" return f"'{value}' || {add_to}"
else: else:
raise DbtRuntimeError(f'Got an unexpected location value of "{location}"') raise RuntimeException(f'Got an unexpected location value of "{location}"')
def get_rows_different_sql( def get_rows_different_sql(
self, self,
@@ -1208,7 +1214,7 @@ class BaseAdapter(metaclass=AdapterMeta):
return self.generate_python_submission_response(submission_result) return self.generate_python_submission_response(submission_result)
def generate_python_submission_response(self, submission_result: Any) -> AdapterResponse: def generate_python_submission_response(self, submission_result: Any) -> AdapterResponse:
raise NotImplementedError( raise NotImplementedException(
"Your adapter need to implement generate_python_submission_response" "Your adapter need to implement generate_python_submission_response"
) )
@@ -1232,7 +1238,7 @@ class BaseAdapter(metaclass=AdapterMeta):
valid_strategies.append("default") valid_strategies.append("default")
builtin_strategies = self.builtin_incremental_strategies() builtin_strategies = self.builtin_incremental_strategies()
if strategy in builtin_strategies and strategy not in valid_strategies: if strategy in builtin_strategies and strategy not in valid_strategies:
raise DbtRuntimeError( raise RuntimeException(
f"The incremental strategy '{strategy}' is not valid for this adapter" f"The incremental strategy '{strategy}' is not valid for this adapter"
) )
@@ -1240,7 +1246,7 @@ class BaseAdapter(metaclass=AdapterMeta):
macro_name = f"get_incremental_{strategy}_sql" macro_name = f"get_incremental_{strategy}_sql"
# The model_context should have MacroGenerator callable objects for all macros # The model_context should have MacroGenerator callable objects for all macros
if macro_name not in model_context: if macro_name not in model_context:
raise DbtRuntimeError( raise RuntimeException(
'dbt could not find an incremental strategy macro with the name "{}" in {}'.format( 'dbt could not find an incremental strategy macro with the name "{}" in {}'.format(
macro_name, self.config.project_name macro_name, self.config.project_name
) )

View File

@@ -1,17 +1,17 @@
from typing import List, Optional, Type from typing import List, Optional, Type
from dbt.adapters.base import Credentials from dbt.adapters.base import Credentials
from dbt.exceptions import CompilationError from dbt.exceptions import CompilationException
from dbt.adapters.protocol import AdapterProtocol from dbt.adapters.protocol import AdapterProtocol
def project_name_from_path(include_path: str) -> str: def project_name_from_path(include_path: str) -> str:
# avoid an import cycle # avoid an import cycle
from dbt.config.project import Project from dbt.config.project import PartialProject
partial = Project.partial_load(include_path) partial = PartialProject.from_project_root(include_path)
if partial.project_name is None: if partial.project_name is None:
raise CompilationError(f"Invalid project at {include_path}: name not set!") raise CompilationException(f"Invalid project at {include_path}: name not set!")
return partial.project_name return partial.project_name

View File

@@ -7,7 +7,7 @@ from dbt.context.manifest import generate_query_header_context
from dbt.contracts.connection import AdapterRequiredConfig, QueryComment from dbt.contracts.connection import AdapterRequiredConfig, QueryComment
from dbt.contracts.graph.nodes import ResultNode from dbt.contracts.graph.nodes import ResultNode
from dbt.contracts.graph.manifest import Manifest from dbt.contracts.graph.manifest import Manifest
from dbt.exceptions import DbtRuntimeError from dbt.exceptions import RuntimeException
class NodeWrapper: class NodeWrapper:
@@ -48,7 +48,7 @@ class _QueryComment(local):
if isinstance(comment, str) and "*/" in comment: if isinstance(comment, str) and "*/" in comment:
# tell the user "no" so they don't hurt themselves by writing # tell the user "no" so they don't hurt themselves by writing
# garbage # garbage
raise DbtRuntimeError(f'query comment contains illegal value "*/": {comment}') raise RuntimeException(f'query comment contains illegal value "*/": {comment}')
self.query_comment = comment self.query_comment = comment
self.append = append self.append = append

View File

@@ -11,11 +11,7 @@ from dbt.contracts.relation import (
Policy, Policy,
Path, Path,
) )
from dbt.exceptions import ( from dbt.exceptions import ApproximateMatch, InternalException, MultipleDatabasesNotAllowed
ApproximateMatchError,
DbtInternalError,
MultipleDatabasesNotAllowedError,
)
from dbt.node_types import NodeType from dbt.node_types import NodeType
from dbt.utils import filter_null_values, deep_merge, classproperty from dbt.utils import filter_null_values, deep_merge, classproperty
@@ -87,7 +83,7 @@ class BaseRelation(FakeAPIObject, Hashable):
if not search: if not search:
# nothing was passed in # nothing was passed in
raise dbt.exceptions.DbtRuntimeError( raise dbt.exceptions.RuntimeException(
"Tried to match relation, but no search path was passed!" "Tried to match relation, but no search path was passed!"
) )
@@ -104,7 +100,7 @@ class BaseRelation(FakeAPIObject, Hashable):
if approximate_match and not exact_match: if approximate_match and not exact_match:
target = self.create(database=database, schema=schema, identifier=identifier) target = self.create(database=database, schema=schema, identifier=identifier)
raise ApproximateMatchError(target, self) raise ApproximateMatch(target, self)
return exact_match return exact_match
@@ -253,14 +249,14 @@ class BaseRelation(FakeAPIObject, Hashable):
) -> Self: ) -> Self:
if node.resource_type == NodeType.Source: if node.resource_type == NodeType.Source:
if not isinstance(node, SourceDefinition): if not isinstance(node, SourceDefinition):
raise DbtInternalError( raise InternalException(
"type mismatch, expected SourceDefinition but got {}".format(type(node)) "type mismatch, expected SourceDefinition but got {}".format(type(node))
) )
return cls.create_from_source(node, **kwargs) return cls.create_from_source(node, **kwargs)
else: else:
# Can't use ManifestNode here because of parameterized generics # Can't use ManifestNode here because of parameterized generics
if not isinstance(node, (ParsedNode)): if not isinstance(node, (ParsedNode)):
raise DbtInternalError( raise InternalException(
f"type mismatch, expected ManifestNode but got {type(node)}" f"type mismatch, expected ManifestNode but got {type(node)}"
) )
return cls.create_from_node(config, node, **kwargs) return cls.create_from_node(config, node, **kwargs)
@@ -358,7 +354,7 @@ class InformationSchema(BaseRelation):
def __post_init__(self): def __post_init__(self):
if not isinstance(self.information_schema_view, (type(None), str)): if not isinstance(self.information_schema_view, (type(None), str)):
raise dbt.exceptions.CompilationError( raise dbt.exceptions.CompilationException(
"Got an invalid name: {}".format(self.information_schema_view) "Got an invalid name: {}".format(self.information_schema_view)
) )
@@ -442,7 +438,7 @@ class SchemaSearchMap(Dict[InformationSchema, Set[Optional[str]]]):
if not allow_multiple_databases: if not allow_multiple_databases:
seen = {r.database.lower() for r in self if r.database} seen = {r.database.lower() for r in self if r.database}
if len(seen) > 1: if len(seen) > 1:
raise MultipleDatabasesNotAllowedError(seen) raise MultipleDatabasesNotAllowed(seen)
for information_schema_name, schema in self.search(): for information_schema_name, schema in self.search():
path = {"database": information_schema_name.database, "schema": schema} path = {"database": information_schema_name.database, "schema": schema}

View File

@@ -9,14 +9,28 @@ from dbt.adapters.reference_keys import (
_ReferenceKey, _ReferenceKey,
) )
from dbt.exceptions import ( from dbt.exceptions import (
DependentLinkNotCachedError, DependentLinkNotCached,
NewNameAlreadyInCacheError, NewNameAlreadyInCache,
NoneRelationFoundError, NoneRelationFound,
ReferencedLinkNotCachedError, ReferencedLinkNotCached,
TruncatedModelNameCausedCollisionError, TruncatedModelNameCausedCollision,
) )
from dbt.events.functions import fire_event, fire_event_if from dbt.events.functions import fire_event, fire_event_if
from dbt.events.types import CacheAction, CacheDumpGraph from dbt.events.types import (
AddLink,
AddRelation,
DropCascade,
DropMissingRelation,
DropRelation,
DumpAfterAddGraph,
DumpAfterRenameSchema,
DumpBeforeAddGraph,
DumpBeforeRenameSchema,
RenameSchema,
TemporaryRelation,
UncachedRelation,
UpdateReference,
)
import dbt.flags as flags import dbt.flags as flags
from dbt.utils import lowercase from dbt.utils import lowercase
@@ -141,7 +155,7 @@ class _CachedRelation:
:raises InternalError: If the new key already exists. :raises InternalError: If the new key already exists.
""" """
if new_key in self.referenced_by: if new_key in self.referenced_by:
raise NewNameAlreadyInCacheError(old_key, new_key) raise NewNameAlreadyInCache(old_key, new_key)
if old_key not in self.referenced_by: if old_key not in self.referenced_by:
return return
@@ -257,17 +271,17 @@ class RelationsCache:
if referenced is None: if referenced is None:
return return
if referenced is None: if referenced is None:
raise ReferencedLinkNotCachedError(referenced_key) raise ReferencedLinkNotCached(referenced_key)
dependent = self.relations.get(dependent_key) dependent = self.relations.get(dependent_key)
if dependent is None: if dependent is None:
raise DependentLinkNotCachedError(dependent_key) raise DependentLinkNotCached(dependent_key)
assert dependent is not None # we just raised! assert dependent is not None # we just raised!
referenced.add_reference(dependent) referenced.add_reference(dependent)
# This is called in plugins/postgres/dbt/adapters/postgres/impl.py # TODO: Is this dead code? I can't seem to find it grepping the codebase.
def add_link(self, referenced, dependent): def add_link(self, referenced, dependent):
"""Add a link between two relations to the database. If either relation """Add a link between two relations to the database. If either relation
does not exist, it will be added as an "external" relation. does not exist, it will be added as an "external" relation.
@@ -289,9 +303,9 @@ class RelationsCache:
# referring to a table outside our control. There's no need to make # referring to a table outside our control. There's no need to make
# a link - we will never drop the referenced relation during a run. # a link - we will never drop the referenced relation during a run.
fire_event( fire_event(
CacheAction( UncachedRelation(
dep_key=_make_msg_from_ref_key(dep_key),
ref_key=_make_msg_from_ref_key(ref_key), ref_key=_make_msg_from_ref_key(ref_key),
ref_key_2=_make_msg_from_ref_key(dep_key),
) )
) )
return return
@@ -304,10 +318,8 @@ class RelationsCache:
dependent = dependent.replace(type=referenced.External) dependent = dependent.replace(type=referenced.External)
self.add(dependent) self.add(dependent)
fire_event( fire_event(
CacheAction( AddLink(
action="add_link", dep_key=_make_msg_from_ref_key(dep_key), ref_key=_make_msg_from_ref_key(ref_key)
ref_key=_make_msg_from_ref_key(dep_key),
ref_key_2=_make_msg_from_ref_key(ref_key),
) )
) )
with self.lock: with self.lock:
@@ -320,18 +332,12 @@ class RelationsCache:
:param BaseRelation relation: The underlying relation. :param BaseRelation relation: The underlying relation.
""" """
cached = _CachedRelation(relation) cached = _CachedRelation(relation)
fire_event_if( fire_event(AddRelation(relation=_make_ref_key_msg(cached)))
flags.LOG_CACHE_EVENTS, fire_event_if(flags.LOG_CACHE_EVENTS, lambda: DumpBeforeAddGraph(dump=self.dump_graph()))
lambda: CacheDumpGraph(before_after="before", action="adding", dump=self.dump_graph()),
)
fire_event(CacheAction(action="add_relation", ref_key=_make_ref_key_msg(cached)))
with self.lock: with self.lock:
self._setdefault(cached) self._setdefault(cached)
fire_event_if( fire_event_if(flags.LOG_CACHE_EVENTS, lambda: DumpAfterAddGraph(dump=self.dump_graph()))
flags.LOG_CACHE_EVENTS,
lambda: CacheDumpGraph(before_after="after", action="adding", dump=self.dump_graph()),
)
def _remove_refs(self, keys): def _remove_refs(self, keys):
"""Removes all references to all entries in keys. This does not """Removes all references to all entries in keys. This does not
@@ -359,19 +365,16 @@ class RelationsCache:
""" """
dropped_key = _make_ref_key(relation) dropped_key = _make_ref_key(relation)
dropped_key_msg = _make_ref_key_msg(relation) dropped_key_msg = _make_ref_key_msg(relation)
fire_event(CacheAction(action="drop_relation", ref_key=dropped_key_msg)) fire_event(DropRelation(dropped=dropped_key_msg))
with self.lock: with self.lock:
if dropped_key not in self.relations: if dropped_key not in self.relations:
fire_event(CacheAction(action="drop_missing_relation", ref_key=dropped_key_msg)) fire_event(DropMissingRelation(relation=dropped_key_msg))
return return
consequences = self.relations[dropped_key].collect_consequences() consequences = self.relations[dropped_key].collect_consequences()
# convert from a list of _ReferenceKeys to a list of ReferenceKeyMsgs # convert from a list of _ReferenceKeys to a list of ReferenceKeyMsgs
consequence_msgs = [_make_msg_from_ref_key(key) for key in consequences] consequence_msgs = [_make_msg_from_ref_key(key) for key in consequences]
fire_event(
CacheAction( fire_event(DropCascade(dropped=dropped_key_msg, consequences=consequence_msgs))
action="drop_cascade", ref_key=dropped_key_msg, ref_list=consequence_msgs
)
)
self._remove_refs(consequences) self._remove_refs(consequences)
def _rename_relation(self, old_key, new_relation): def _rename_relation(self, old_key, new_relation):
@@ -394,14 +397,12 @@ class RelationsCache:
for cached in self.relations.values(): for cached in self.relations.values():
if cached.is_referenced_by(old_key): if cached.is_referenced_by(old_key):
fire_event( fire_event(
CacheAction( UpdateReference(
action="update_reference", old_key=_make_ref_key_msg(old_key),
ref_key=_make_ref_key_msg(old_key), new_key=_make_ref_key_msg(new_key),
ref_key_2=_make_ref_key_msg(new_key), cached_key=_make_ref_key_msg(cached.key()),
ref_key_3=_make_ref_key_msg(cached.key()),
) )
) )
cached.rename_key(old_key, new_key) cached.rename_key(old_key, new_key)
self.relations[new_key] = relation self.relations[new_key] = relation
@@ -426,12 +427,10 @@ class RelationsCache:
if new_key in self.relations: if new_key in self.relations:
# Tell user when collision caused by model names truncated during # Tell user when collision caused by model names truncated during
# materialization. # materialization.
raise TruncatedModelNameCausedCollisionError(new_key, self.relations) raise TruncatedModelNameCausedCollision(new_key, self.relations)
if old_key not in self.relations: if old_key not in self.relations:
fire_event( fire_event(TemporaryRelation(key=_make_msg_from_ref_key(old_key)))
CacheAction(action="temporary_relation", ref_key=_make_msg_from_ref_key(old_key))
)
return False return False
return True return True
@@ -450,16 +449,13 @@ class RelationsCache:
old_key = _make_ref_key(old) old_key = _make_ref_key(old)
new_key = _make_ref_key(new) new_key = _make_ref_key(new)
fire_event( fire_event(
CacheAction( RenameSchema(
action="rename_relation", old_key=_make_msg_from_ref_key(old_key), new_key=_make_msg_from_ref_key(new)
ref_key=_make_msg_from_ref_key(old_key),
ref_key_2=_make_msg_from_ref_key(new),
) )
) )
fire_event_if( fire_event_if(
flags.LOG_CACHE_EVENTS, flags.LOG_CACHE_EVENTS, lambda: DumpBeforeRenameSchema(dump=self.dump_graph())
lambda: CacheDumpGraph(before_after="before", action="rename", dump=self.dump_graph()),
) )
with self.lock: with self.lock:
@@ -469,8 +465,7 @@ class RelationsCache:
self._setdefault(_CachedRelation(new)) self._setdefault(_CachedRelation(new))
fire_event_if( fire_event_if(
flags.LOG_CACHE_EVENTS, flags.LOG_CACHE_EVENTS, lambda: DumpAfterRenameSchema(dump=self.dump_graph())
lambda: CacheDumpGraph(before_after="after", action="rename", dump=self.dump_graph()),
) )
def get_relations(self, database: Optional[str], schema: Optional[str]) -> List[Any]: def get_relations(self, database: Optional[str], schema: Optional[str]) -> List[Any]:
@@ -490,7 +485,7 @@ class RelationsCache:
] ]
if None in results: if None in results:
raise NoneRelationFoundError() raise NoneRelationFound()
return results return results
def clear(self): def clear(self):

View File

@@ -10,7 +10,7 @@ from dbt.adapters.protocol import AdapterConfig, AdapterProtocol, RelationProtoc
from dbt.contracts.connection import AdapterRequiredConfig, Credentials from dbt.contracts.connection import AdapterRequiredConfig, Credentials
from dbt.events.functions import fire_event from dbt.events.functions import fire_event
from dbt.events.types import AdapterImportError, PluginLoadError from dbt.events.types import AdapterImportError, PluginLoadError
from dbt.exceptions import DbtInternalError, DbtRuntimeError from dbt.exceptions import InternalException, RuntimeException
from dbt.include.global_project import PACKAGE_PATH as GLOBAL_PROJECT_PATH from dbt.include.global_project import PACKAGE_PATH as GLOBAL_PROJECT_PATH
from dbt.include.global_project import PROJECT_NAME as GLOBAL_PROJECT_NAME from dbt.include.global_project import PROJECT_NAME as GLOBAL_PROJECT_NAME
@@ -34,7 +34,7 @@ class AdapterContainer:
names = ", ".join(self.plugins.keys()) names = ", ".join(self.plugins.keys())
message = f"Invalid adapter type {name}! Must be one of {names}" message = f"Invalid adapter type {name}! Must be one of {names}"
raise DbtRuntimeError(message) raise RuntimeException(message)
def get_adapter_class_by_name(self, name: str) -> Type[Adapter]: def get_adapter_class_by_name(self, name: str) -> Type[Adapter]:
plugin = self.get_plugin_by_name(name) plugin = self.get_plugin_by_name(name)
@@ -60,7 +60,7 @@ class AdapterContainer:
# the user about it via a runtime error # the user about it via a runtime error
if exc.name == "dbt.adapters." + name: if exc.name == "dbt.adapters." + name:
fire_event(AdapterImportError(exc=str(exc))) fire_event(AdapterImportError(exc=str(exc)))
raise DbtRuntimeError(f"Could not find adapter type {name}!") raise RuntimeException(f"Could not find adapter type {name}!")
# otherwise, the error had to have come from some underlying # otherwise, the error had to have come from some underlying
# library. Log the stack trace. # library. Log the stack trace.
@@ -70,7 +70,7 @@ class AdapterContainer:
plugin_type = plugin.adapter.type() plugin_type = plugin.adapter.type()
if plugin_type != name: if plugin_type != name:
raise DbtRuntimeError( raise RuntimeException(
f"Expected to find adapter with type named {name}, got " f"Expected to find adapter with type named {name}, got "
f"adapter with type {plugin_type}" f"adapter with type {plugin_type}"
) )
@@ -132,7 +132,7 @@ class AdapterContainer:
try: try:
plugin = self.plugins[plugin_name] plugin = self.plugins[plugin_name]
except KeyError: except KeyError:
raise DbtInternalError(f"No plugin found for {plugin_name}") from None raise InternalException(f"No plugin found for {plugin_name}") from None
plugins.append(plugin) plugins.append(plugin)
seen.add(plugin_name) seen.add(plugin_name)
for dep in plugin.dependencies: for dep in plugin.dependencies:
@@ -151,7 +151,7 @@ class AdapterContainer:
try: try:
path = self.packages[package_name] path = self.packages[package_name]
except KeyError: except KeyError:
raise DbtInternalError(f"No internal package listing found for {package_name}") raise InternalException(f"No internal package listing found for {package_name}")
paths.append(path) paths.append(path)
return paths return paths

View File

@@ -27,7 +27,9 @@ class SQLConnectionManager(BaseConnectionManager):
@abc.abstractmethod @abc.abstractmethod
def cancel(self, connection: Connection): def cancel(self, connection: Connection):
"""Cancel the given connection.""" """Cancel the given connection."""
raise dbt.exceptions.NotImplementedError("`cancel` is not implemented for this adapter!") raise dbt.exceptions.NotImplementedException(
"`cancel` is not implemented for this adapter!"
)
def cancel_open(self) -> List[str]: def cancel_open(self) -> List[str]:
names = [] names = []
@@ -93,7 +95,7 @@ class SQLConnectionManager(BaseConnectionManager):
@abc.abstractmethod @abc.abstractmethod
def get_response(cls, cursor: Any) -> AdapterResponse: def get_response(cls, cursor: Any) -> AdapterResponse:
"""Get the status of the cursor.""" """Get the status of the cursor."""
raise dbt.exceptions.NotImplementedError( raise dbt.exceptions.NotImplementedException(
"`get_response` is not implemented for this adapter!" "`get_response` is not implemented for this adapter!"
) )
@@ -149,7 +151,7 @@ class SQLConnectionManager(BaseConnectionManager):
def begin(self): def begin(self):
connection = self.get_thread_connection() connection = self.get_thread_connection()
if connection.transaction_open is True: if connection.transaction_open is True:
raise dbt.exceptions.DbtInternalError( raise dbt.exceptions.InternalException(
'Tried to begin a new transaction on connection "{}", but ' 'Tried to begin a new transaction on connection "{}", but '
"it already had one open!".format(connection.name) "it already had one open!".format(connection.name)
) )
@@ -162,7 +164,7 @@ class SQLConnectionManager(BaseConnectionManager):
def commit(self): def commit(self):
connection = self.get_thread_connection() connection = self.get_thread_connection()
if connection.transaction_open is False: if connection.transaction_open is False:
raise dbt.exceptions.DbtInternalError( raise dbt.exceptions.InternalException(
'Tried to commit transaction on connection "{}", but ' 'Tried to commit transaction on connection "{}", but '
"it does not have one open!".format(connection.name) "it does not have one open!".format(connection.name)
) )

View File

@@ -2,7 +2,7 @@ import agate
from typing import Any, Optional, Tuple, Type, List from typing import Any, Optional, Tuple, Type, List
from dbt.contracts.connection import Connection from dbt.contracts.connection import Connection
from dbt.exceptions import RelationTypeNullError from dbt.exceptions import RelationTypeNull
from dbt.adapters.base import BaseAdapter, available from dbt.adapters.base import BaseAdapter, available
from dbt.adapters.cache import _make_ref_key_msg from dbt.adapters.cache import _make_ref_key_msg
from dbt.adapters.sql import SQLConnectionManager from dbt.adapters.sql import SQLConnectionManager
@@ -131,7 +131,7 @@ class SQLAdapter(BaseAdapter):
def drop_relation(self, relation): def drop_relation(self, relation):
if relation.type is None: if relation.type is None:
raise RelationTypeNullError(relation) raise RelationTypeNull(relation)
self.cache_dropped(relation) self.cache_dropped(relation)
self.execute_macro(DROP_RELATION_MACRO_NAME, kwargs={"relation": relation}) self.execute_macro(DROP_RELATION_MACRO_NAME, kwargs={"relation": relation})

View File

@@ -0,0 +1 @@
from .main import cli as dbt_cli # noqa

16
core/dbt/cli/context.py Normal file
View File

@@ -0,0 +1,16 @@
import click
from typing import Optional
from dbt.cli.main import cli as dbt
def make_context(args, command=dbt) -> Optional[click.Context]:
try:
ctx = command.make_context(command.name, args)
except click.exceptions.Exit:
return None
ctx.invoked_subcommand = ctx.protected_args[0] if ctx.protected_args else None
ctx.obj = {}
return ctx

20
core/dbt/cli/example.py Normal file
View File

@@ -0,0 +1,20 @@
from dbt.cli.main import dbtRunner
from dbt.config.runtime import load_profile, load_project
if __name__ == "__main__":
project_dir = "/Users/chenyuli/git/jaffle_shop"
cli_args = ["run", "--project-dir", project_dir]
# initialize the dbt runner
dbt = dbtRunner()
# run the command
res, success = dbt.invoke(cli_args)
# preload profile and project
profile = load_profile(project_dir, {}, "testing-postgres")
project = load_project(project_dir, False, profile, {})
# initialize the runner with pre-loaded profile and project, you can also pass in a preloaded manifest
dbt = dbtRunner(profile=profile, project=project)
# run the command, this will use the pre-loaded profile and project instead of loading
res, success = dbt.invoke(cli_args)

View File

@@ -1,10 +1,17 @@
# TODO Move this to /core/dbt/flags.py when we're ready to break things # TODO Move this to /core/dbt/flags.py when we're ready to break things
import os import os
import sys
from dataclasses import dataclass from dataclasses import dataclass
from importlib import import_module
from multiprocessing import get_context from multiprocessing import get_context
from pprint import pformat as pf from pprint import pformat as pf
from typing import Set
from click import get_current_context from click import Context, get_current_context
from click.core import ParameterSource
from dbt.config.profile import read_user_config
from dbt.contracts.project import UserConfig
if os.name != "nt": if os.name != "nt":
# https://bugs.python.org/issue41567 # https://bugs.python.org/issue41567
@@ -13,12 +20,12 @@ if os.name != "nt":
@dataclass(frozen=True) @dataclass(frozen=True)
class Flags: class Flags:
def __init__(self, ctx=None) -> None: def __init__(self, ctx: Context = None, user_config: UserConfig = None) -> None:
if ctx is None: if ctx is None:
ctx = get_current_context() ctx = get_current_context()
def assign_params(ctx): def assign_params(ctx, params_assigned_from_default):
"""Recursively adds all click params to flag object""" """Recursively adds all click params to flag object"""
for param_name, param_value in ctx.params.items(): for param_name, param_value in ctx.params.items():
# N.B. You have to use the base MRO method (object.__setattr__) to set attributes # N.B. You have to use the base MRO method (object.__setattr__) to set attributes
@@ -27,18 +34,57 @@ class Flags:
if hasattr(self, param_name): if hasattr(self, param_name):
raise Exception(f"Duplicate flag names found in click command: {param_name}") raise Exception(f"Duplicate flag names found in click command: {param_name}")
object.__setattr__(self, param_name.upper(), param_value) object.__setattr__(self, param_name.upper(), param_value)
if ctx.get_parameter_source(param_name) == ParameterSource.DEFAULT:
params_assigned_from_default.add(param_name)
if ctx.parent: if ctx.parent:
assign_params(ctx.parent) assign_params(ctx.parent, params_assigned_from_default)
assign_params(ctx) params_assigned_from_default = set() # type: Set[str]
assign_params(ctx, params_assigned_from_default)
# Get the invoked command flags
invoked_subcommand_name = (
ctx.invoked_subcommand if hasattr(ctx, "invoked_subcommand") else None
)
if invoked_subcommand_name is not None:
invoked_subcommand = getattr(import_module("dbt.cli.main"), invoked_subcommand_name)
invoked_subcommand.allow_extra_args = True
invoked_subcommand.ignore_unknown_options = True
invoked_subcommand_ctx = invoked_subcommand.make_context(None, sys.argv)
assign_params(invoked_subcommand_ctx, params_assigned_from_default)
if not user_config:
profiles_dir = getattr(self, "PROFILES_DIR", None)
user_config = read_user_config(profiles_dir) if profiles_dir else None
# Overwrite default assignments with user config if available
if user_config:
for param_assigned_from_default in params_assigned_from_default:
user_config_param_value = getattr(user_config, param_assigned_from_default, None)
if user_config_param_value is not None:
object.__setattr__(
self, param_assigned_from_default.upper(), user_config_param_value
)
# Hard coded flags # Hard coded flags
object.__setattr__(self, "WHICH", ctx.info_name) object.__setattr__(self, "WHICH", invoked_subcommand_name or ctx.info_name)
object.__setattr__(self, "MP_CONTEXT", get_context("spawn")) object.__setattr__(self, "MP_CONTEXT", get_context("spawn"))
# Support console DO NOT TRACK initiave # Support console DO NOT TRACK initiave
if os.getenv("DO_NOT_TRACK", "").lower() in (1, "t", "true", "y", "yes"): object.__setattr__(
object.__setattr__(self, "ANONYMOUS_USAGE_STATS", False) self,
"ANONYMOUS_USAGE_STATS",
False
if os.getenv("DO_NOT_TRACK", "").lower() in ("1", "t", "true", "y", "yes")
else True,
)
# Support lower cased access for legacy code
params = set(
x for x in dir(self) if not callable(getattr(self, x)) and not x.startswith("__")
)
for param in params:
object.__setattr__(self, param.lower(), getattr(self, param))
def __str__(self) -> str: def __str__(self) -> str:
return str(pf(self.__dict__)) return str(pf(self.__dict__))

View File

@@ -1,14 +1,20 @@
import inspect # This is temporary for RAT-ing import inspect # This is temporary for RAT-ing
from copy import copy from copy import copy
from pprint import pformat as pf # This is temporary for RAT-ing from pprint import pformat as pf # This is temporary for RAT-ing
from typing import List, Tuple, Optional
import click import click
from dbt.adapters.factory import adapter_management from dbt.cli import requires, params as p
from dbt.cli import params as p from dbt.config import RuntimeConfig
from dbt.cli.flags import Flags from dbt.config.project import Project
from dbt.profiler import profiler from dbt.config.profile import Profile
from dbt.contracts.graph.manifest import Manifest
from dbt.task.clean import CleanTask
from dbt.task.deps import DepsTask
from dbt.task.run import RunTask
# CLI invocation
def cli_runner(): def cli_runner():
# Alias "list" to "ls" # Alias "list" to "ls"
ls = copy(cli.commands["list"]) ls = copy(cli.commands["list"])
@@ -19,6 +25,31 @@ def cli_runner():
cli() cli()
class dbtUsageException(Exception):
pass
# Programmatic invocation
class dbtRunner:
def __init__(
self, project: Project = None, profile: Profile = None, manifest: Manifest = None
):
self.project = project
self.profile = profile
self.manifest = manifest
def invoke(self, args: List[str]) -> Tuple[Optional[List], bool]:
try:
dbt_ctx = cli.make_context(cli.name, args)
dbt_ctx.obj = {}
dbt_ctx.obj["project"] = self.project
dbt_ctx.obj["profile"] = self.profile
dbt_ctx.obj["manifest"] = self.manifest
return cli.invoke(dbt_ctx)
except (click.NoSuchOption, click.UsageError) as e:
raise dbtUsageException(e.message)
# dbt # dbt
@click.group( @click.group(
context_settings={"help_option_names": ["-h", "--help"]}, context_settings={"help_option_names": ["-h", "--help"]},
@@ -34,39 +65,29 @@ def cli_runner():
@p.fail_fast @p.fail_fast
@p.log_cache_events @p.log_cache_events
@p.log_format @p.log_format
@p.log_path
@p.macro_debugging @p.macro_debugging
@p.partial_parse @p.partial_parse
@p.print @p.print
@p.printer_width @p.printer_width
@p.quiet @p.quiet
@p.record_timing_info @p.record_timing_info
@p.single_threaded
@p.static_parser @p.static_parser
@p.use_colors @p.use_colors
@p.use_experimental_parser @p.use_experimental_parser
@p.version @p.version
@p.version_check @p.version_check
@p.warn_error @p.warn_error
@p.warn_error_options
@p.write_json @p.write_json
def cli(ctx, **kwargs): def cli(ctx, **kwargs):
"""An ELT tool for managing your SQL transformations and data models. """An ELT tool for managing your SQL transformations and data models.
For more documentation on these commands, visit: docs.getdbt.com For more documentation on these commands, visit: docs.getdbt.com
""" """
incomplete_flags = Flags()
# Profiling
if incomplete_flags.RECORD_TIMING_INFO:
ctx.with_resource(profiler(enable=True, outfile=incomplete_flags.RECORD_TIMING_INFO))
# Adapter management
ctx.with_resource(adapter_management())
# Version info # Version info
if incomplete_flags.VERSION: if ctx.params["version"]:
click.echo(f"`version` called\n ctx.params: {pf(ctx.params)}") click.echo(f"`version` called\n ctx.params: {pf(ctx.params)}")
return return
else:
del ctx.params["version"]
# dbt build # dbt build
@@ -77,11 +98,10 @@ def cli(ctx, **kwargs):
@p.fail_fast @p.fail_fast
@p.full_refresh @p.full_refresh
@p.indirect_selection @p.indirect_selection
@p.log_path
@p.models
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.select
@p.selector @p.selector
@p.show @p.show
@p.state @p.state
@@ -91,10 +111,11 @@ def cli(ctx, **kwargs):
@p.threads @p.threads
@p.vars @p.vars
@p.version_check @p.version_check
@requires.preflight
def build(ctx, **kwargs): def build(ctx, **kwargs):
"""Run all Seeds, Models, Snapshots, and tests in DAG order""" """Run all Seeds, Models, Snapshots, and tests in DAG order"""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt clean # dbt clean
@@ -105,10 +126,16 @@ def build(ctx, **kwargs):
@p.project_dir @p.project_dir
@p.target @p.target
@p.vars @p.vars
@requires.preflight
@requires.profile
@requires.project
def clean(ctx, **kwargs): def clean(ctx, **kwargs):
"""Delete all folders in the clean-targets list (usually the dbt_packages and target directories.)""" """Delete all folders in the clean-targets list (usually the dbt_packages and target directories.)"""
flags = Flags() task = CleanTask(ctx.obj["flags"], ctx.obj["project"])
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}")
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt docs # dbt docs
@@ -124,11 +151,10 @@ def docs(ctx, **kwargs):
@p.compile_docs @p.compile_docs
@p.defer @p.defer
@p.exclude @p.exclude
@p.log_path
@p.models
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.select
@p.selector @p.selector
@p.state @p.state
@p.target @p.target
@@ -136,10 +162,11 @@ def docs(ctx, **kwargs):
@p.threads @p.threads
@p.vars @p.vars
@p.version_check @p.version_check
@requires.preflight
def docs_generate(ctx, **kwargs): def docs_generate(ctx, **kwargs):
"""Generate the documentation website for your project""" """Generate the documentation website for your project"""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt docs serve # dbt docs serve
@@ -152,10 +179,11 @@ def docs_generate(ctx, **kwargs):
@p.project_dir @p.project_dir
@p.target @p.target
@p.vars @p.vars
@requires.preflight
def docs_serve(ctx, **kwargs): def docs_serve(ctx, **kwargs):
"""Serve the documentation website for your project""" """Serve the documentation website for your project"""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt compile # dbt compile
@@ -164,12 +192,11 @@ def docs_serve(ctx, **kwargs):
@p.defer @p.defer
@p.exclude @p.exclude
@p.full_refresh @p.full_refresh
@p.log_path
@p.models
@p.parse_only @p.parse_only
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.select
@p.selector @p.selector
@p.state @p.state
@p.target @p.target
@@ -177,10 +204,11 @@ def docs_serve(ctx, **kwargs):
@p.threads @p.threads
@p.vars @p.vars
@p.version_check @p.version_check
@requires.preflight
def compile(ctx, **kwargs): def compile(ctx, **kwargs):
"""Generates executable SQL from source, model, test, and analysis files. Compiled SQL files are written to the target/ directory.""" """Generates executable SQL from source, model, test, and analysis files. Compiled SQL files are written to the target/ directory."""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt debug # dbt debug
@@ -193,10 +221,11 @@ def compile(ctx, **kwargs):
@p.target @p.target
@p.vars @p.vars
@p.version_check @p.version_check
@requires.preflight
def debug(ctx, **kwargs): def debug(ctx, **kwargs):
"""Show some helpful information about dbt for debugging. Not to be confused with the --debug option which increases verbosity.""" """Show some helpful information about dbt for debugging. Not to be confused with the --debug option which increases verbosity."""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt deps # dbt deps
@@ -207,10 +236,16 @@ def debug(ctx, **kwargs):
@p.project_dir @p.project_dir
@p.target @p.target
@p.vars @p.vars
@requires.preflight
@requires.profile
@requires.project
def deps(ctx, **kwargs): def deps(ctx, **kwargs):
"""Pull the most recent version of the dependencies listed in packages.yml""" """Pull the most recent version of the dependencies listed in packages.yml"""
flags = Flags() task = DepsTask(ctx.obj["flags"], ctx.obj["project"])
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}")
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt init # dbt init
@@ -222,10 +257,11 @@ def deps(ctx, **kwargs):
@p.skip_profile_setup @p.skip_profile_setup
@p.target @p.target
@p.vars @p.vars
@requires.preflight
def init(ctx, **kwargs): def init(ctx, **kwargs):
"""Initialize a new DBT project.""" """Initialize a new DBT project."""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt list # dbt list
@@ -233,28 +269,28 @@ def init(ctx, **kwargs):
@click.pass_context @click.pass_context
@p.exclude @p.exclude
@p.indirect_selection @p.indirect_selection
@p.models
@p.output @p.output
@p.output_keys @p.output_keys
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.resource_type @p.resource_type
@p.select
@p.selector @p.selector
@p.state @p.state
@p.target @p.target
@p.vars @p.vars
@requires.preflight
def list(ctx, **kwargs): def list(ctx, **kwargs):
"""List the resources in your project""" """List the resources in your project"""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt parse # dbt parse
@cli.command("parse") @cli.command("parse")
@click.pass_context @click.pass_context
@p.compile_parse @p.compile_parse
@p.log_path
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@@ -264,10 +300,11 @@ def list(ctx, **kwargs):
@p.vars @p.vars
@p.version_check @p.version_check
@p.write_manifest @p.write_manifest
@requires.preflight
def parse(ctx, **kwargs): def parse(ctx, **kwargs):
"""Parses the project and provides information on performance""" """Parses the project and provides information on performance"""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt run # dbt run
@@ -277,11 +314,10 @@ def parse(ctx, **kwargs):
@p.exclude @p.exclude
@p.fail_fast @p.fail_fast
@p.full_refresh @p.full_refresh
@p.log_path
@p.models
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.select
@p.selector @p.selector
@p.state @p.state
@p.target @p.target
@@ -289,10 +325,17 @@ def parse(ctx, **kwargs):
@p.threads @p.threads
@p.vars @p.vars
@p.version_check @p.version_check
@requires.preflight
@requires.profile
@requires.project
def run(ctx, **kwargs): def run(ctx, **kwargs):
"""Compile SQL and execute against the current target database.""" """Compile SQL and execute against the current target database."""
flags = Flags() config = RuntimeConfig.from_parts(ctx.obj["project"], ctx.obj["profile"], ctx.obj["flags"])
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") task = RunTask(ctx.obj["flags"], config)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt run operation # dbt run operation
@@ -304,10 +347,11 @@ def run(ctx, **kwargs):
@p.project_dir @p.project_dir
@p.target @p.target
@p.vars @p.vars
@requires.preflight
def run_operation(ctx, **kwargs): def run_operation(ctx, **kwargs):
"""Run the named macro with any supplied arguments.""" """Run the named macro with any supplied arguments."""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt seed # dbt seed
@@ -315,11 +359,10 @@ def run_operation(ctx, **kwargs):
@click.pass_context @click.pass_context
@p.exclude @p.exclude
@p.full_refresh @p.full_refresh
@p.log_path
@p.models
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.select
@p.selector @p.selector
@p.show @p.show
@p.state @p.state
@@ -328,10 +371,11 @@ def run_operation(ctx, **kwargs):
@p.threads @p.threads
@p.vars @p.vars
@p.version_check @p.version_check
@requires.preflight
def seed(ctx, **kwargs): def seed(ctx, **kwargs):
"""Load data from csv files into your data warehouse.""" """Load data from csv files into your data warehouse."""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt snapshot # dbt snapshot
@@ -339,19 +383,20 @@ def seed(ctx, **kwargs):
@click.pass_context @click.pass_context
@p.defer @p.defer
@p.exclude @p.exclude
@p.models
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.select
@p.selector @p.selector
@p.state @p.state
@p.target @p.target
@p.threads @p.threads
@p.vars @p.vars
@requires.preflight
def snapshot(ctx, **kwargs): def snapshot(ctx, **kwargs):
"""Execute snapshots defined in your project""" """Execute snapshots defined in your project"""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt source # dbt source
@@ -365,20 +410,21 @@ def source(ctx, **kwargs):
@source.command("freshness") @source.command("freshness")
@click.pass_context @click.pass_context
@p.exclude @p.exclude
@p.models
@p.output_path # TODO: Is this ok to re-use? We have three different output params, how much can we consolidate? @p.output_path # TODO: Is this ok to re-use? We have three different output params, how much can we consolidate?
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.select
@p.selector @p.selector
@p.state @p.state
@p.target @p.target
@p.threads @p.threads
@p.vars @p.vars
@requires.preflight
def freshness(ctx, **kwargs): def freshness(ctx, **kwargs):
"""Snapshots the current freshness of the project's sources""" """Snapshots the current freshness of the project's sources"""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# dbt test # dbt test
@@ -388,11 +434,10 @@ def freshness(ctx, **kwargs):
@p.exclude @p.exclude
@p.fail_fast @p.fail_fast
@p.indirect_selection @p.indirect_selection
@p.log_path
@p.models
@p.profile @p.profile
@p.profiles_dir @p.profiles_dir
@p.project_dir @p.project_dir
@p.select
@p.selector @p.selector
@p.state @p.state
@p.store_failures @p.store_failures
@@ -401,10 +446,11 @@ def freshness(ctx, **kwargs):
@p.threads @p.threads
@p.vars @p.vars
@p.version_check @p.version_check
@requires.preflight
def test(ctx, **kwargs): def test(ctx, **kwargs):
"""Runs tests on data in deployed models. Run this after `dbt run`""" """Runs tests on data in deployed models. Run this after `dbt run`"""
flags = Flags() click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}")
click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {flags}") return None, True
# Support running as a module # Support running as a module

Some files were not shown because too many files have changed in this diff Show More