Compare commits

...

799 Commits

Author SHA1 Message Date
Emily Rockman
c429d2d136 fix change kind (#9964) 2024-04-17 15:40:16 -05:00
Emily Rockman
f815b03178 bump sqlparse to 0.5 (#9951)
* bump sqlparse

* changelog
# Conflicts:
#	core/setup.py
2024-04-17 15:40:02 -05:00
Emily Rockman
a5c6d54baa [1.7] Fix Workflow Deprecations (#9799) (#9911) 2024-04-17 07:46:55 -05:00
Emily Rockman
677e2bc9d1 be less explicit (#9936) (#9944) 2024-04-15 12:26:54 -05:00
Emily Rockman
83a9f88c03 update to wrk for all versions (#9916) (#9917)
# Conflicts:
#	.github/workflows/main.yml
2024-04-15 08:00:03 -05:00
FishtownBuildBot
885d5f0701 [Automated] Merged prep-release/1.5.11_8469709936 into target 1.5.latest during release process 2024-03-28 11:02:02 -05:00
Github Build Bot
61db9208b0 Bumping version to 1.5.11 and generate changelog 2024-03-28 15:32:42 +00:00
Quigley Malcolm
afb675c767 Restrict protobuf to 4.* versions (#9630) (#9708)
Protobuf v5 has breaking changes. Here we are limiting the protobuf
dependency to one major version, 4, so that we don't have to patch
over handling 2 different major versions of protobuf.
2024-02-29 10:42:19 -08:00
FishtownBuildBot
a404cf6073 [Automated] Merged prep-release/1.5.10_8087144220 into target 1.5.latest during release process 2024-02-28 13:43:18 -08:00
Github Build Bot
b6f8b08a78 Bumping version to 1.5.10 and generate changelog 2024-02-28 21:14:22 +00:00
Quigley Malcolm
c94f132177 [Backport 1.5.latest] Restrict to protobuf 4 (#9676)
* Restrict protobuf to version 4.

* Restrict protobuf to major version 4.

---------

Co-authored-by: Peter Allen Webb <peter.webb@dbtlabs.com>
2024-02-26 15:35:28 -08:00
Quigley Malcolm
b2270fa38a [Backport 1.5.latest] Upgrade Jinja2 dependency version specification to address CVE-2024-22195 (#9670)
* Upgrade Jinja2 dependency version specification to address CVE-2024-22195 (#9638)

CVE-2024-22195 identified an issue in Jinja2 versions <= 3.1.2. As such
we've gone and changed our dependency requirement specification to be
3.1.3 or greater (but less than 4).

Note: Preivously we were using the `~=` version specifier. However due
to some issues with the `~=` we've moved to using `>=` in combination
with `<`. This gives us the same range that `~=` gave us, but avoids
a pip resolution issue when multiple packages in an environment use `~=`
for the same dependency.
2024-02-26 15:09:30 -08:00
github-actions[bot]
dc3e667792 [Backport 1.5.latest] Pin pytest in dev-requirements.txt (#9476)
Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>
2024-01-30 16:45:31 +00:00
github-actions[bot]
5bbdab618d test pinning ddtrace (#9090) (#9094)
(cherry picked from commit 3902137dfc)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-11-15 17:04:59 -06:00
FishtownBuildBot
2708be3a82 [Automated] Merged prep-release/1.5.9_6709967767 into target 1.5.latest during release process 2023-10-31 13:45:40 -04:00
Github Build Bot
470fb5ede0 Bumping version to 1.5.9 and generate changelog 2023-10-31 17:06:11 +00:00
github-actions[bot]
4e250ad941 Contract enforcement on temporary tables (#8889) (#8904)
* add test

* fix test

* first pass with constraint error

* add back column checks for temp tables

* changelog

* Update .changes/unreleased/Fixes-20231024-145504.yaml

(cherry picked from commit 98310b6612)

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2023-10-26 10:00:46 -05:00
FishtownBuildBot
01b78980f1 [Automated] Merged prep-release/1.5.8_6485826531 into target 1.5.latest during release process 2023-10-11 13:54:42 -04:00
Github Build Bot
5262489f24 Bumping version to 1.5.8 and generate changelog 2023-10-11 17:15:53 +00:00
Jeremy Cohen
d81da57731 [Backport 1.5.latest] Fix #6497: Support global flags passed in after subcommands (#8734)
Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>
2023-10-11 16:18:15 +01:00
Michelle Ark
3c8cf858a2 [Backport 1.5.latest] respect project root when loading seeds (#8762) (#8805)
(cherry picked from commit 964e0e4e8a)
2023-10-11 15:55:24 +01:00
github-actions[bot]
543f87e17f [Backport 1.5.latest] Fix #8022: Foreign key constraint on incremental model results in Database Error (#8807)
(cherry picked from commit 6461f5aacf)

Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>
2023-10-11 14:48:07 +01:00
github-actions[bot]
885a8a9652 Fix uncaught exception for group updates (#8792) (#8813)
* add test

* write test

* fix test

* updating test

* add clean

* cleanup

* more tests, fix comment

* add new test, move fixtures

(cherry picked from commit 4f9bd0cb38)

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2023-10-10 16:23:51 -05:00
Emily Rockman
6510a8b810 support doc blocks (#8771) (#8785) 2023-10-10 09:58:20 -05:00
FishtownBuildBot
c85aee1616 [Automated] Merged prep-release/1.5.7_6344197726 into target 1.5.latest during release process 2023-09-28 17:32:56 -05:00
Github Build Bot
41395c1bfb Bumping version to 1.5.7 and generate changelog 2023-09-28 21:42:48 +00:00
github-actions[bot]
6fb39bf35b Fix: avoid double-rendering sql_header in dbt show (#8740) (#8742)
(cherry picked from commit 408a78985a)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-09-28 14:19:06 -05:00
Emily Rockman
13816dc4df update changelog type (#8735) 2023-09-28 08:21:01 -07:00
Michelle Ark
4875c31bbd Inline limit in SQL sent from dbt show (#8641) (#8731) 2023-09-27 20:36:16 +01:00
Emily Rockman
76a276ca58 Support quoted parameter list for MultiOption cli options (#8665) (#8703)
* allow multioption to be quoted

* changelog

* fix test

* remove list format

* fix tests

* fix list object

* review arg change

* fix quotes

* Update .changes/unreleased/Features-20230918-150855.yaml

* add types

* convert list to set in test

* make mypy happy

* mroe mypy happiness

* more mypy happiness

* last mypy change

* add node to test
2023-09-26 09:59:04 -05:00
Emily Rockman
3862ef956a [BACKPORT] Split integration tests into parallel groups / jobs (#6346) (#8603)
* Split integration tests into parallel groups / jobs (#6346)

# Conflicts:
#	.github/workflows/main.yml

* rename job

---------

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-09-11 16:09:41 -05:00
Emily Rockman
00a5b3a9c8 Support dbt-cloud config dict in dbt_project.yml (#8527) (#8556)
* first pass at adding dbt-cloud config

* changelog

* fix test, add direct validation
2023-09-05 14:35:01 -05:00
Gerda Shank
3be943edb0 Fix snapshot success message to display "INSERT 0 1" (for example) instead of success (#8524) (#8531) 2023-08-31 14:55:44 -04:00
FishtownBuildBot
42addafa07 [Automated] Merged prep-release/1.5.6_5929068153 into target 1.5.latest during release process 2023-08-21 12:15:20 -05:00
Github Build Bot
46a90cab4d Bumping version to 1.5.6 and generate changelog 2023-08-21 16:41:55 +00:00
github-actions[bot]
96a222387a revert python version for docker images (#8445) (#8447)
* revert python version for docker images

* add comment to not update python version, update changelog

(cherry picked from commit f485c13035)

Co-authored-by: Matthew McKnight <91097623+McKnight-42@users.noreply.github.com>
2023-08-18 10:59:10 -05:00
FishtownBuildBot
fe2a5ba326 [Automated] Merged prep-release/1.5.5_5894165573 into target 1.5.latest during release process 2023-08-17 13:24:47 -05:00
Github Build Bot
bdc3adcabe Bumping version to 1.5.5 and generate changelog 2023-08-17 17:45:21 +00:00
github-actions[bot]
85c77acd80 Fix using project-dir with list command and path selector (#8388) (#8428)
(cherry picked from commit 048553ddc3)

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2023-08-16 18:10:23 -04:00
Emily Rockman
8394bbd278 pin upper bound for sqlparse (#8236) (#8239)
* pin upper bound for sqlparse

* changelog
# Conflicts:
#	core/setup.py

Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com>
2023-08-15 17:56:46 -07:00
Emily Rockman
dd7a3293da loosen the click pin (#8232) (#8252)
* loosen the click pin

* changelog

* separate out sqlparse pin

* remove changelog

* add ignores

Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com>
2023-08-15 14:00:19 -07:00
Gerda Shank
4b21acdaad [Backport 1.5.latest] Ensure that target_schema from snapshot config is promoted to node level (#8117) (#8231)
(cherry-picked from fe9c875d32)
2023-08-15 13:36:38 -04:00
github-actions[bot]
5fc6d4d273 add a node status (#8174) (#8179)
(cherry picked from commit 0d645c227f)

Co-authored-by: Chenyu Li <chenyu.li@dbtlabs.com>
2023-08-15 11:44:54 +08:00
github-actions[bot]
a84883818f add env vars to tox.ini (#8365) (#8369)
* add env vars to tox.ini

* revert test

(cherry picked from commit b7aee3f5a4)

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2023-08-11 15:41:15 -05:00
github-actions[bot]
045a6d8412 add param to control maxBytes for single dbt.log file (#8200) (#8241)
* add param to control maxBytes for single dbt.log file

* nits

* nits

* Update core/dbt/cli/params.py

Co-authored-by: Peter Webb <peter.webb@dbtlabs.com>

---------

Co-authored-by: Peter Webb <peter.webb@dbtlabs.com>
(cherry picked from commit f392add4b8)

Co-authored-by: Chenyu Li <chenyu.li@dbtlabs.com>
2023-08-01 13:12:38 -07:00
FishtownBuildBot
ed92f1369c [Automated] Merged prep-release/1.5.4_5692874947 into target 1.5.latest during release process 2023-07-28 09:54:48 -05:00
Github Build Bot
1be5a0cae8 Bumping version to 1.5.4 and generate changelog 2023-07-28 14:11:49 +00:00
FishtownBuildBot
a658072f77 [Automated] Merged prep-release/1.5.4rc1_5683294297 into target 1.5.latest during release process 2023-07-27 12:42:26 -05:00
Github Build Bot
7083c0e14f Bumping version to 1.5.4rc1 and generate changelog 2023-07-27 16:54:16 +00:00
Gerda Shank
a98b69c77c [Backport 1.5.latest] Initialize sqlparse lexer and tweak order of setting compilation fields (#8215) (#8221)
(cherry picked from commit fdeccfaf24)
2023-07-27 11:42:05 -04:00
Gerda Shank
fac2f62ea8 [Backport 1.5.latest] Rearrange pp_versioned_models test (#8157)
* Rearrange pp_versioned_models test (#8150)

(cherry picked from commit a32713198b)

* Do the equivalent of rename_if_exists
2023-07-26 12:06:49 -04:00
Quigley Malcolm
d39c53d160 [CT-2594] Backport #8180 to 1.5.latest (#8198)
* Add test ensuring `warn_error_options` is dictified in `invocation_args_dict` of contexts

* Add dictification specific to `warn_error_options` in `args_to_dict`

* Changie doc for serialization changes of warn_error_options
2023-07-24 16:00:55 -07:00
github-actions[bot]
d26028876f [Backport 1.5.latest] Hotfix for 372: Use JSONEncoder in json.dumps (#8163)
Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>
2023-07-21 16:06:38 -05:00
Emily Rockman
0d8f6d0784 add env vars for datadog ci visibility (#8097) (#8107)
* add env vars for datadog ci visibility

* modify pytest command for tracing

* fix posargs

* move env vars to job that needs them

* add test repeater to DD

* swap flags
# Conflicts:
#	.github/workflows/test-repeater.yml
2023-07-18 08:17:21 -05:00
FishtownBuildBot
efdbb2b9e2 [Automated] Merged prep-release/1.5.3_5578590246 into target 1.5.latest during release process 2023-07-17 12:57:43 -05:00
Github Build Bot
4bd3a40e4c Bumping version to 1.5.3 and generate changelog 2023-07-17 17:17:22 +00:00
Michelle Ark
774e905e26 Backport 8072 1.5.latest3 (#8084)
* Always build contract checksum for versioned model

* changelog entry
2023-07-13 12:14:43 +02:00
github-actions[bot]
2d7582997a Nicer error message for contracted model missing 'columns' (#8024) (#8041)
(cherry picked from commit 746ca7d149)

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2023-07-11 20:20:08 +02:00
Emily Rockman
f466740cc5 pin click (#8050) (#8052)
* pin click

* changelog
# Conflicts:
#	core/setup.py
2023-07-07 12:38:17 -05:00
github-actions[bot]
b3975dbd96 allow on_schema_change: fail for incremental models with contracts (#8006) (#8037)
(cherry picked from commit 7ea51df6ae)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-07-06 11:53:34 +02:00
Jeremy Cohen
3e5e693442 fire proper event for inline query error (#7960) (#8021) 2023-07-05 08:36:14 -07:00
Gerda Shank
a935df97ca [BACKPORT to 1.5.latest] Remove pin of sqlparse to below 0.4.4 (#8008)
* Remove pin of sqlparse to below 0.4.4

* Changie
2023-06-30 13:54:37 -04:00
Gerda Shank
98fcb4ac55 Use events.contextvar because of multiprocessing unable to pickle ContextVar (#7949) (#7981)
Cherry-picked from commit 2e7c96841

* Add task contextvars to events/contextvars.py

* Use events.contextvars instead of task.contextvars

* Changie
2023-06-30 08:50:03 -04:00
Jeremy Cohen
b1874006e6 Add target_path to more cli commands that use it (#7647) (#7961)
Co-authored-by: Daniel Reeves <31971762+dwreeves@users.noreply.github.com>
2023-06-28 11:27:34 +02:00
FishtownBuildBot
66dd15b29d [Automated] Merged prep-release/1.5.2_5347682028 into target 1.5.latest during release process 2023-06-22 11:43:53 -05:00
Github Build Bot
39702dc4b7 Bumping version to 1.5.2 and generate changelog 2023-06-22 15:57:55 +00:00
FishtownBuildBot
36e6c67d47 [Automated] Merged prep-release/1.5.2rc2_5291645992 into target 1.5.latest during release process 2023-06-16 11:05:56 -05:00
Github Build Bot
043e511ec0 Bumping version to 1.5.2rc2 and generate changelog 2023-06-16 15:31:40 +00:00
colin-rogers-dbt
9776e7a7e8 backport 7862 to 1.5.latest (#7878)
* cherry pick f767943fb2

* Regenerate event proto types

---------

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2023-06-16 11:23:15 -04:00
github-actions[bot]
e1a9d9f94f Readd exp_path for config deprecation warnings (#7536) (#7737)
(cherry picked from commit 9c7e01dbca)

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-06-14 13:15:52 -04:00
Jeremy Cohen
57dacb02b9 Backport #7838 to 1.5.latest (#7875)
* Changelog entry

* Fix: `dbt show --inline` with `private` models (#7838)

* Add functional test

* Check resource_type before DbtReferenceError

* Changelog entry
2023-06-14 13:15:34 -04:00
github-actions[bot]
49627fcac8 add ability to select models by access (#7739) (#7801) 2023-06-14 13:14:17 -04:00
github-actions[bot]
126d68732a Respect column quote config in model contracts (#7537) (#7858)
(cherry picked from commit 83d163add5)

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-06-14 09:50:52 -04:00
github-actions[bot]
83f02516b1 generalize BaseModelConstraintsRuntimeEnforcement (#7805) (#7852) 2023-06-14 00:43:41 -04:00
Emily Rockman
693a338642 [Backport] #7779 to 1.5.latest (#7856)
* update adapters url (#7779)

* update adapters url

in response to [docs.getedbt.com pr 3465](https://github.com/dbt-labs/docs.getdbt.com/issues/3465), updating this error message to point to the correct URL, which was recently changed.

old URL: https://docs.getdbt.com/docs/supported-data-platforms#adapter-installation
new URL: https://docs.getdbt.com/docs/connect-adapters#install-using-the-cli

thank you @dbeatty10 for your 🦅 👀 !

* adding changie entry

* Update .changes/unreleased/Breaking Changes-20230612-161159.yaml

---------

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
# Conflicts:
#	core/dbt/exceptions.py

* update error msg

---------

Co-authored-by: mirnawong1 <89008547+mirnawong1@users.noreply.github.com>
2023-06-13 16:04:59 -05:00
github-actions[bot]
11d9f9979e Use project directory in path selector instead of cwd (#7829) (#7850)
(cherry picked from commit ca73a2aa15)

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2023-06-13 11:34:09 -04:00
github-actions[bot]
27eb48c1ff Fix constraint rendering for expressions and foreign key constraint types (#7512) (#7784)
(cherry picked from commit 05b0ebb184)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-06-09 16:48:52 -04:00
FishtownBuildBot
7f2bdbf85d [Automated] Merged prep-release/1.5.2rc1_5215591201 into target 1.5.latest during release process 2023-06-08 16:30:51 -05:00
Github Build Bot
66e0644558 Bumping version to 1.5.2rc1 and generate changelog 2023-06-08 20:50:36 +00:00
Emily Rockman
3a81fa9f47 add --target-path to snapshot command (#7419) (#7826)
Co-authored-by: Daniel Reeves <31971762+dwreeves@users.noreply.github.com>
2023-06-08 13:45:20 -05:00
github-actions[bot]
467cae06a2 Version 0 for model works for latest_version (#7712) (#7780)
(cherry picked from commit 79bd98560b)

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2023-06-08 10:05:05 -04:00
github-actions[bot]
d94d6518e1 fix error message for empty/None: --warn-error-options handling (#7735) (#7817) 2023-06-07 13:49:52 -04:00
Emily Rockman
963a38fece [BACKPORT] Improve warning for constraints and mat types (#7806)
* Improve warnings for constraints and materialization types (#7696)

* first pass

* debugging

* regen proto types

* refactor to use warn_supported flag

* PR feedback

* regen proto files after conflicts

* fix problems wqith conflict resolution
2023-06-07 10:20:12 -05:00
github-actions[bot]
e5bd8b0233 pass optional sql_header to empty subquery sql rendering (#7734) (#7768) 2023-06-05 12:35:23 -04:00
Gerda Shank
f8cc136bf7 Target path should be relative to project dir, rather than current working directory (#7706) (#7715) 2023-06-05 10:20:05 -04:00
FishtownBuildBot
de9ee6a580 [Automated] Merged prep-release/1.5.1_5122894882 into target 1.5.latest during release process 2023-05-30 10:19:30 -05:00
Github Build Bot
a4ed7cefcb Bumping version to 1.5.1 and generate changelog 2023-05-30 14:46:14 +00:00
FishtownBuildBot
355f918afd [Automated] Merged prep-release/1.5.1rc2_5081528232 into target 1.5.latest during release process 2023-05-25 10:56:26 -05:00
Github Build Bot
630681b57f Bumping version to 1.5.1rc2 and generate changelog 2023-05-25 15:08:24 +00:00
github-actions[bot]
890bc168f3 CT 2516 ensure that paths in Jinja context flags object are strings (#7678) (#7692)
(cherry picked from commit 0516192d69)

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2023-05-25 09:40:44 -04:00
github-actions[bot]
a3e6a487ef Missed PR fedback (#7642) (#7691)
(cherry picked from commit df23f68dd4)

Co-authored-by: Ian Knox <81931810+iknox-fa@users.noreply.github.com>
2023-05-24 08:29:13 -04:00
github-actions[bot]
8887c0ca0b bugfix: Deps hangs when using relative paths via --project-dir (#7628) (#7643)
(cherry picked from commit dcb5acdf29)

Co-authored-by: Ian Knox <81931810+iknox-fa@users.noreply.github.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2023-05-23 19:30:51 -07:00
Peter Webb
b06a8ebef4 Remove DelayedFileHandler (#7661) (#7683)
* remove DelayedFileHandler

* Changelog

* set_path to no-op

* more no-ops for rpc

* Clearer comments

Co-authored-by: Ian Knox <81931810+iknox-fa@users.noreply.github.com>
2023-05-23 09:54:47 -04:00
Emily Rockman
06c7a8a9cb Allow missing profiles.yml for dbt deps and dbt init (#7546) (#7677)
* Allow missing `profiles.yml` for `dbt deps` and `dbt init`

* Some commands allow the `--profiles-dir` to not exist

* Remove fix to verify that CI tests work

* Allow missing `profiles.yml` for `dbt deps` and `dbt init`

* CI is not finding any installed adapters

* Remove functional test for `dbt init`

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2023-05-22 15:28:26 -05:00
Peter Webb
19e2f2e8ce Profile Jinja Rendering, 1.5 Backport (#7653)
* Exclude some profile fields from Jinja rendering when they are not valid Jinja. (#7630)

* CT-2583: Exclude some profile fields from Jinja rendering.

* CT-2583: Add functional test.

* CT-2583: Change approach to password jinja detection

* CT-2583: Extract string constant and add additional checks

* CT-2583: Improve unit test coverage

* CT-2583: Update changelog entry to reflect new approach
2023-05-18 09:34:30 -04:00
Emily Rockman
9804e6715d cherry pick 7fbeced315 (#7638) 2023-05-16 11:48:50 -05:00
Gerda Shank
9642789817 CT 2510 Throw error for duplicate versioned and non versioned model n… (#7605)
* CT 2510 Throw error for duplicate versioned and non versioned model names (#7577)

* Check for versioned/unversioned duplicates

* Add new exception DuplicateVersionedUnversionedError

* Changie

* Handle packages when finding versioned and unversioned duplicates

(cherry picked from commit 29f2cfc48d)

* Issue AmbiguousAlias error after DuplicateResourceName
2023-05-12 15:42:36 -04:00
FishtownBuildBot
7844ac4bf4 [Automated] Merged prep-release/1.5.1rc1_4960109758 into target 1.5.latest during release process 2023-05-12 10:29:02 -05:00
Github Build Bot
7fa6ce8aa4 Bumping version to 1.5.1rc1 and generate changelog 2023-05-12 14:49:05 +00:00
Kshitij Aranke
2a3cab9ec7 Backport dbt show enhancements into 1.5.latest (#7578) 2023-05-11 09:44:58 -07:00
github-actions[bot]
c578e5b080 fix #7407: print model version in dbt show if specified (#7543) (#7557)
(cherry picked from commit 40aca4bc17)

Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>
2023-05-10 09:41:21 -04:00
github-actions[bot]
cb9e4d5dae [Fix] Typo in statically parsed ref unpacking (#7365) (#7572)
test statically parsed two-argument ref

(cherry picked from commit 0891aef8d7)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-05-09 18:51:06 -04:00
github-actions[bot]
70c98a5495 CT 2552 pin protobuf to >=4.0.0 (#7566) (#7567)
* Pin protobuf to >=4.0.0

* Changie

(cherry picked from commit d34c511fa5)

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2023-05-09 13:52:38 -04:00
github-actions[bot]
14796b2bd4 Do not rewrite manifest.json during 'docs serve' command (#7554) (#7555)
(cherry picked from commit 5a7b73be26)

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2023-05-09 09:33:52 -04:00
github-actions[bot]
0cd20fffc3 Fix inverted --print/--no-print flag (#7524) (#7547)
(cherry picked from commit 19d6dab973)

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2023-05-08 15:39:38 -04:00
Jeremy Cohen
251917198c Back compat for previous return type of collect_freshness (#7535) (#7548)
* Back compat for previous retrurn type of 'collect_freshness'

* Test fixups

* PR feedback
2023-05-08 15:39:02 -04:00
FishtownBuildBot
2eaa4f084c [Automated] Merged prep-release/1.5.0_4819829606 into target 1.5.latest during release process 2023-04-27 08:24:23 -05:00
Github Build Bot
dafb6aeb93 Bumping version to 1.5.0 and generate changelog 2023-04-27 12:41:02 +00:00
github-actions[bot]
c79a65828f UX improvements to model versions (#7435) (#7462)
* Latest version should use un-suffixed alias

* Latest version can be in un-suffixed file

* FYI when unpinned ref to model with prerelease version

* [WIP] Nicer error if versioned ref to unversioned model

* Revert "Latest version should use un-suffixed alias"

This reverts commit 3616c52c1eed7588b9e210e1c957dfda598be550.

* Revert "[WIP] Nicer error if versioned ref to unversioned model"

This reverts commit c9ae4af1cfbd6b7bfc5dcbb445556233eb4bd2c0.

* Define real event for UnpinnedRefNewVersionAvailable

* Update pp test for implicit unsuffixed defined_in

* Add changelog entry

* Fix unit test

* marky feedback

* Add test case for UnpinnedRefNewVersionAvailable event

(cherry picked from commit d53bb37186)

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2023-04-26 11:53:19 +02:00
github-actions[bot]
f37cb927ae Fix groupable node partial parsing, raise DbtReferenceError in RuntimeRefResolver (#7438) (#7461)
(cherry picked from commit 9874f9e004)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-04-25 14:04:44 -04:00
github-actions[bot]
77867d76f8 fix partial parsing of versioned models - schedule child nodes if latest version has been modified (#7439) (#7460)
(cherry picked from commit 2739d5f4c4)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-04-25 12:01:17 -04:00
FishtownBuildBot
1da608f2a0 [Automated] Merged prep-release/1.5.0rc2_4758640507 into target 1.5.latest during release process 2023-04-20 16:12:09 -05:00
Github Build Bot
1b6cf1a67f Bumping version to 1.5.0rc2 and generate changelog 2023-04-20 20:37:48 +00:00
github-actions[bot]
1d24e94e5d fix target dir behavior with sources.json (#7412) (#7423) 2023-04-20 15:54:13 -04:00
github-actions[bot]
437870eb13 fix v0 ref resolution and latest_version configuration(#7415) (#7422) 2023-04-20 15:26:09 -04:00
github-actions[bot]
dee5e70a06 sqlparse <0.4.4 (#7394) (#7398)
(cherry picked from commit 57e9096816)

Co-authored-by: Michelle Ark <MichelleArk@users.noreply.github.com>
2023-04-19 22:18:07 -04:00
github-actions[bot]
f0530e66b3 [Fix] safe version attribute access in _check_resource_uniqueness (#7376) (#7405)
safe version attribute access in _check_resource_uniqueness
2023-04-19 21:50:28 -04:00
github-actions[bot]
faa279d38d Update docs link in ContractBreakingChangeError message (#7367) (#7392)
(cherry picked from commit 6fedfe0ece)

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2023-04-19 08:56:05 +02:00
github-actions[bot]
c1f3cc1f13 Update --help text for cache-related parameters (#7389) (#7409)
(cherry picked from commit ada8860e48)

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2023-04-19 08:54:20 +02:00
Kshitij Aranke
d6526b037c Run 'changie new' on 1.5.latest branch (#7380) 2023-04-18 09:48:23 -07:00
Mike Alfare
ffb5a8ff37 updating make recipe for explicit order (#7385) 2023-04-18 01:08:19 -04:00
FishtownBuildBot
a67c14ee87 [Automated] Merged prep-release/1.5.0rc1_4694810085 into target 1.5.latest during release process 2023-04-13 19:20:25 -05:00
Github Build Bot
9ffe2647ee Bumping version to 1.5.0rc1 and generate changelog 2023-04-13 23:45:51 +00:00
Kshitij Aranke
06437df286 dbt 1.5.0rc1 (#7355) 2023-04-13 16:31:28 -07:00
Michelle Ark
74419b0e86 [Fix] Fix versioned model selection in subdirectories (#7351)
* fix versioned model selection in subdirectories
2023-04-13 10:58:52 -04:00
Jeremy Cohen
2ddf296a8e Adding a new column is not a breaking contract change (#7333)
* Adding a new column is not a breaking contract change

* Add changelog entry

* More structured exception

* same_contract: False if non-breaking changes

* PR feedback: rm build_contract_checksum, more comments
2023-04-13 00:19:46 +02:00
Chenyu Li
6b42a712a8 remove providing profile/project to dbtRunner (#7337) 2023-04-12 12:23:48 -07:00
Benoît Allard
c3230d3374 Allow greater mashumaro versions (#7294)
* Allow greater mashumaro versions

Current 3.5 is working fine.

* Pin mashumaro to 3.6 (released 4 days ago)

* Add changie
2023-04-12 14:40:54 -04:00
Chenyu Li
602535fe71 compile inline query doesn't add node (#7326)
* remove inline node after compile

* add test

* unset inline node
2023-04-12 09:03:55 -07:00
FishtownBuildBot
f9b28bcaed Add new index.html and changelog yaml files from dbt-docs (#7328)
Co-authored-by: Michelle Ark <michelle.ark@dbtlabs.com>
2023-04-12 11:19:49 -04:00
Gerda Shank
922c75344b Add access, has_group, contract_enforced, versioned to run_model (#7309) 2023-04-12 10:56:10 -04:00
Michelle Ark
2caf87c247 Add version selector method (#7330)
Add version selector method: "latest", "prerelease", "old", and "none" selectors supported
2023-04-12 10:48:17 -04:00
Michelle Ark
f2a3535c3f add schema_string_type fixture to test_constraints (#7229) 2023-04-12 10:27:00 -04:00
Peter Webb
a500e60b7f Reset invocation_id Between Commands (#7317)
* CT-2317: Reset invocation id in preflight for each dbt command.

* CT-2317: Add unit test for invocation_id behavior.

* CT-2317: Add changelog entry.

* CT-2317: Modify freshness test to ignore invocation_id

* CT-2317: Assign invocation_id before tracking initialization.

* CT-2317: Fix unit test failures and a bunch of other stuff

* CT-2317: Remove checks which make outdated assumptions about invocation_id being stable between runs

* CT-2317: Review tweak, more unit test fixes.
2023-04-12 09:54:17 -04:00
Michelle Ark
c7ebc8935f model versions (#7287)
model versioning and versioned ref resolution
2023-04-12 09:50:39 -04:00
Neelesh Salian
56f8f8a329 Fix for simple snapshot for seed and test assert (#7296)
* Fix for simple snapshot for seed and test assert

* Bigquery varchar type fix
2023-04-11 19:20:41 -07:00
Doug Beatty
828d723512 Update help text for commands + params in CLI and top-level API (#7176)
* Removed options for `dbt parse`

* Fix misspellings

* Capitalize JSON when appropriate

* Update help text for --write-json/--no-write-json

* Update help text for --config-dir

* Update help text for --resource-types

* Removed decorators for removed dbt parse options

* Remove `--write-manifest` flag from `parse`

* Remove `--parse-only` flag from `compile`

* Update help text for `dbt list --output`

* Standardize on one line per argument

* Factor 3 from 12 Factor CLI Apps

* Update help text for `dbt --version`

* Standardize capitalization of resource types for `dbt build`

* `debug --config-dir` is a boolean flag

* Update help text for `--version-check`

* Specify `-q` as a conventional alias for `--quiet`

* Update help text for `debug --config-dir`

* Update help text for `debug`

* Treat more dense text blobs as binary for `git grep`

* Update help text for `--version-check`

* Update help text for `--defer`

* Update help text for `--indirect-selection`

* Co-locate log colorization with other log settings

* Update help text for `--log-format*`, `--log-level*`, and `--use-colors*`

* Temporarily re-add option for CI tests

* Remove `--parse-only` flag from `show`

* Remove `--write-manifest` flag from `parse` (again)
2023-04-11 17:09:00 -06:00
Robbert Hofman
b450a5754e Snapshot strategies: newline for subquery (#6780)
* Snapshot strategies: newline for subquery

* add changie output

* add test for snapshot ending in comment

* remove import to be flake8 compliant

* add seed import

* add newlines for flake8 compliance

* typo fix

* Fixing up a test, adding a comment or two

* removed un-needed test fixtures

* removed even more un-needed fixtures, collapsed test to single class

* removed errant breakpoint()

* Fix a little typo

---------

Co-authored-by: Ian Knox <ian.knox@dbtlabs.com>
Co-authored-by: Mila Page <67295367+VersusFacit@users.noreply.github.com>
2023-04-11 14:49:36 -07:00
Emily Rockman
2971b9a027 Generalize constraint warnings (#7250)
* CT-1922: Rough in functionality for parsing model level constraints

* CT-1922: (Almost) complete support for model level constraints

* CT-1922: Fix typo affecting correct model constraint parsing.

* CT-1922: Rework base class for model tests for greater simplicity

* CT-1922: Rough in functionality for parsing model level constraints

* CT-1922: Revise unit tests for new model-level constraints property

* CT-1922: (Almost) complete support for model level constraints

* first pass

* implement in core

* add proto

* WIP

* resolve errors in columns_spec_ddl

* changelog

* update comment

* move logic over to python

* rename and use enum

* update default constraint_support dict

* generate new proto definition after conflicts

* reorganize code and break warnings into each constraint

* fix postgres constraint support

* remove breakpoint

* convert constraint support to constant

* update postgres

* add to export

* add to export

* regen proto types file

* standardize names

* put back mypy error

* more naming + add back comma

* add constraint support to model level constraints

* update event message and method signature

* rename method

* CT-1922: Rough in functionality for parsing model level constraints

* CT-1922: Revise unit tests for new model-level constraints property

* CT-1922: (Almost) complete support for model level constraints

* CT-1922: Fix typo affecting correct model constraint parsing.

* CT-1922: Improve whitespace handling

* CT-1922: Render raw constraints to constraint list directly

* make method return consistent

* regenerate proto defn

* update evvent test

* add some code cleanup

---------

Co-authored-by: Peter Allen Webb <peter.webb@dbtlabs.com>
2023-04-11 14:25:55 -05:00
Chenyu Li
3c54959829 remove functions and added time to remove the rest (#7270)
* remove functions and added time to remove the rest

* completely remove lib.py
2023-04-11 11:58:09 -07:00
Stu Kilgore
87e25e8692 Add option to skip relation cache population (#7307) 2023-04-11 13:15:23 -05:00
Peter Webb
6ac5c90a0b CT-1922: Parsing and postgres implementations for model level constraints (#7230)
* CT-1922: Rough in functionality for parsing model level constraints

* CT-1922: Revise unit tests for new model-level constraints property

* CT-1922: (Almost) complete support for model level constraints

* CT-1922: Fix typo affecting correct model constraint parsing.

* CT-1922: Minor code review refinements

* CT-1922: Improve whitespace handling

* CT-1922: Render raw constraints to constraint list directly

* CT-1922: Rework base class for model tests for greater simplicity

* CT-1922: Remove debugging properties. Oops.

* CT-1922: Fix type annotation
2023-04-11 13:59:03 -04:00
Ian Knox
a58fb24e2b Handle duplicated flags better (#7303) 2023-04-11 11:49:15 -05:00
dave-connors-3
9ce593c47f allow resources to be selected by patch path (#7321)
* allow resources to be selected by patch path

* don't ever changie

* use hasattr

* Ignore mypy complaints about patch_path

---------

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2023-04-11 12:30:46 -04:00
Jeremy Cohen
c9d4051136 Rebase #7223: improve contracts error message (#7319)
* improved first line of error

* added basic printing of yaml and sql cols as columns

* added changie log

* used listed dictionary as input to match columns

* swapped order of col headers for printing

* used listed dictionary as input to match columns

* removed merge conflict text from file

* Touch-ups

* Update log introspection in functional tests

* Update format_column macro. Case insensitive test

* PR feedback: just data_type, not formatted

---------

Co-authored-by: Kyle Kent <kyle.kent321@gmail.com>
2023-04-11 18:27:23 +02:00
Jeremy Cohen
26f3518cea Update CLI/API docs example, header (#7320)
* Rm CLI/API example

* Update autogen docs header
2023-04-11 18:27:05 +02:00
Ian Knox
49eed67ab0 Parse command should return manifest when invoked via dbtRunner (#7314) 2023-04-11 10:37:56 -05:00
Matteo Ferrando
7a4d3bd2dc fix: avoid dbtRunner default callbacks being shared across instances (#7279)
* fix: avoid dbtRunner default callbacks being shared across instances

* changie
2023-04-11 10:43:17 +02:00
Stu Kilgore
2afb4ccd68 Handle internal exceptions in postflight (#7242) 2023-04-10 17:25:51 -05:00
Gerda Shank
f38d5ad8e2 Add unique_id to CompiledNode and ShowNode logging events (#7308) 2023-04-10 17:09:01 -04:00
Jeremy Cohen
7e1f04c667 Prettify ListRelations message (#7311) 2023-04-10 23:02:01 +02:00
Jeremy Cohen
ef2ba39dcf Add relation info to node_info in logging (#7304)
* Add db, schema, alias, rel_name to node_info

* Add changelog entry

* Default to None

* Nested node_relation message
2023-04-10 22:16:54 +02:00
Tobie Tusing
7045e11aa0 Remove trivial nodes before building subdag (#7194)
* remove trial nodes before building subdag

* add changie

* Update graph.py

remove comment

* further optimize by sorting node search by degree

* change degree to product of in and out degree
2023-04-07 12:09:58 -04:00
Neelesh Salian
a9016c37f5 Fix the base classes of simple snapshot for better import (#7293) 2023-04-07 08:26:38 -07:00
Neelesh Salian
fe62ab8ec5 Moving simple_snapshot test from individual adapters to core adapter zone (#7275)
* Simple snapshot adapter zone

* Class naming

* Class name to Base

* delete extra test file
2023-04-06 18:18:47 -07:00
Gerda Shank
893daedc42 Ensure that same_contract is called for state:modified (#7283) 2023-04-06 15:45:25 -04:00
Doug Beatty
44be13b006 Avoid revoking grants for views when copy_grants=true (#7285)
* Replace hard-coded parameter with intended variable instead

* Changelog entry
2023-04-06 11:37:20 -06:00
Quigley Malcolm
a5131ecc7d CT-2264, CT-2259, CT-1783: Improved event serialization failure handling (#7249)
* Add tests for logging jinja2.Undefined objects

[CT-2259](https://github.com/dbt-labs/dbt-core/issues/7108) identifies
an issue wherein dbt-core 1.0-1.3 raise errors if a jinja2.Undefined
object is attempted to be logged. This generally happened in the form
of `{{ log(undefined_variable, info=True) }}`. This commit adding this
test exists for two reasons
1. Ensure we don't have a regression in this going forward
2. Exist as a commit to be used for backport fixes for dbt-core 1.0-1.3

* Add tests for checking `DBT_ENV_SECRET_`s don't break logging

[CT-1783](https://github.com/dbt-labs/dbt-core/issues/6568) describes
a bug in dbt-core 1.0-1.3 wherein when a `DBT_ENV_SECRET_` all
`{{ log("logging stuff", info=True) }}` invocations break. This commit
adds a test for this for two reasons:
1. Ensure we don't regress to this behavior going forward
2. Act as a base commit for making the backport fixes to dbt-core 1.0-1.3

* Add tests ensuring failed event serialization is handled correctly

[CT-2264](https://github.com/dbt-labs/dbt-core/issues/7113) states
that failed serialization should result in an exception handling path
which will fire another event instead of raising an exception. This is
hard to test perfectly because the exception handling path for
serialization depending on whether pytest is present. If pytest isn't
present, a new event documentation the failed serialization is fired.
If pytest is present, the failed serialization gets raised as an exception.
Thus this added test ensures that the expected exception is raised and
assumes that the correct event will be fired normally.

* Log warning when event serialization fails in `msg_to_dict`

This commit updates the `msg_to_dict` exception handling path to
fire a warning level event instead of raising an exception.
Truthfully, we're not sure if this exception handling path is even
possible to hit. That's because we recently switched from betterproto
to google's protobuf. However, exception path is the subject of
[CT-2264](https://github.com/dbt-labs/dbt-core/issues/7113). Though we
don't think it's actually possible to hit it anymore, we still want
to handle the case if it is.

* Update serialization failure note to be a warn level event in `BaseEvent`

[CT-2264](https://github.com/dbt-labs/dbt-core/issues/7113) wants
logging messages about event serialization failure to be `WARNING`
level events. This does that.

* Add changie info for changes

* Add test to check exception handling of `msg_to_dict`
2023-04-05 19:11:03 -07:00
Kshitij Aranke
ce5d02569f Add kwargs support to dbtRunner (#7274) 2023-04-05 09:40:12 -07:00
Jeremy Cohen
4fc7456000 Small logging fix: stringify datetimes in messages (#7257)
* Stringify datetimes for logging messages

* Add changelog
2023-04-05 15:33:45 +02:00
Kshitij Aranke
28e3412556 New command: dbt show (#7208) 2023-04-04 16:28:22 -07:00
Gerda Shank
86fe510bcf CT 2346 fix read and check versions (#7253) 2023-04-04 18:13:14 -04:00
dependabot[bot]
eaedbd3187 Bump python from 3.11.1-slim-bullseye to 3.11.2-slim-bullseye in /docker (#7196)
* Bump python from 3.11.1-slim-bullseye to 3.11.2-slim-bullseye in /docker

Bumps python from 3.11.1-slim-bullseye to 3.11.2-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-04-04 09:31:43 -04:00
Ryan Hill
b31fcc4edf Add double to float types for columns (#6897)
* add double to float types for columns

* add changie item
2023-04-03 14:51:39 -07:00
Emily Rockman
edb5634b9a remove deprecated exception functions (#7251)
* remove deprecated exception functions

* fully remove deprecated exception functions
2023-04-03 09:43:24 -05:00
Gerda Shank
ad21458e10 Fix DepsNotifyUpdatesAvailable logging event (#7262) 2023-04-03 10:11:53 -04:00
dependabot[bot]
622bc43ced Bump black from 22.12.0 to 23.3.0 (#7243)
* Bump black from 22.12.0 to 23.3.0

Bumps [black](https://github.com/psf/black) from 22.12.0 to 23.3.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/22.12.0...23.3.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-03-31 09:55:56 -04:00
FishtownBuildBot
e5d99da0bc [Automated] Merged prep-release/1.5.0b5_4566650829 into target main during release process 2023-03-30 11:53:45 -05:00
Github Build Bot
618499b379 Bumping version to 1.5.0b5 and generate changelog 2023-03-30 16:21:36 +00:00
Gerda Shank
bca361acf9 Remove unnecessary "version" keys in partial parsing pp_dict (#7238) 2023-03-29 16:15:57 -04:00
Ian Knox
567e2ca2be [Missed Commit] Replace tracking events: project_id, adapter_info (#7240) 2023-03-29 14:18:53 -05:00
Ian Knox
474143466f Replace tracking events: project_id, adapter_info (#7231) 2023-03-29 09:41:22 -05:00
Gerda Shank
050161c78f Detect breaking changes to column names and data types in state:modified check (#7216) 2023-03-28 19:54:55 -04:00
Emily Rockman
ab496af1f0 convert contract to dict (#7222)
* first pass at changes before modifying tests

* test updates

* add default

* update manifest

* fix tests

* changelog

* fix unit tests

* rename strict -> enforced

* convert to object

* fix tests

* Update Under the Hood-20230217-105223.yaml

* Update Under the Hood-20230217-105223.yaml

* remove stray breakpoints

* move Contract definition to model_config

* fix contract reference
2023-03-28 17:21:03 -05:00
Doug Beatty
c3c2b27e97 Allow --select and --exclude multiple times (#7169)
* One argument per line

* Tests for multiple `--select` or `--exclude`

* Allow `--select` and `--exclude` multiple times

* Changelog entry

* MultiOption options must be specified with type=tuple or type=ChoiceTuple

* Testing for `--output-keys` and `--resource-type`

* Validate that any new param with `MultiOption` should also have `type=tuple` (or `ChoiceTuple`) and `multiple=True`
2023-03-28 10:50:55 -06:00
Emily Rockman
5789d717ba Enforce model contracts for incremental materializations (#7167)
* first pass

* adding tests

* changelog

* split up tests due to order importance

* update test

* add back comment

* rename base test classes

* move sql

* fix test name

* move sql

* test changes to match main

* organize and cleanup fixtures

* more cleanup of tests
2023-03-28 11:25:24 -05:00
Vyacheslav
14e2c3ec21 CT-2129 Bug: added timeout for dbt version (#7009)
* CT-2129: added timeout for dbt version

* CT-2129: updated CHANGELOG.md

* delete the files added under core/dbt/.changes
2023-03-27 17:13:28 -07:00
Gerda Shank
b718c537a7 Raise upper pin for hologram to 0.0.16 (#7221) 2023-03-27 13:40:25 -04:00
Stu Kilgore
6992151081 Add postflight to handle click exc and exit codes (#7212) 2023-03-27 11:49:37 -05:00
Matthieu Blais
bf5ed39db3 Filter out already existing edges in the subgraph created while building the job queue (#7192) 2023-03-24 13:08:18 -05:00
Gerda Shank
f573870232 Use function for datetime in CommandCompleted and throw error when testing (#7217) 2023-03-24 10:52:01 -04:00
Quigley Malcolm
da4a90aa11 CT-1928: dbtRunner to EventManager callback support (#7214)
* add utility function to EventManager for explicitly adding callbacks

Technically these aren't necessary in their current state. We could instead
have people do `<InstantiatedEventManager>.callbacks.extend(...)` directly.
However, it's not hard to imagine a world wherein extra things need to take
place when a callback is added. Thus abstracting to a utility method
now means that as the implementation of how callbacks are actually added
changes, the invocation to do so can stay the same.

* update `setup_event_logger` to optionally take in callbacks add them to the EventManager

* update preflight decorator to check for and pass along callbacks for event logger setup

* Add `callbacks` to `dbtRunner`

On instantiation of `dbtRunner` one can now provide `callbacks`. These
callbacks are for the `EventLogger`. When `invoke` is called on a `dbtRunner`,
the `callbacks` are added to the cli context object. In the preflight
decorator these callbacks are extracted from the cli context and then
passed to the `setup_event_logger`, finally `setup_event_logger` ensures
the callbacks are added to the global `EVENT_MANAGER`.

* add test to check dbtRunner callbacks get properly set

I believe technically this tests qualifies as more of an integration
test, but no other tests like it currently exist (that I could find
via a cursory search). The `tests/unit/test_dbt_runner.py` seemed like
the most intuitive spot. However, if somewhere else makes sense, I'd be
happy to move it.

* add changie documentation for CT-1928
2023-03-22 17:32:01 -07:00
Mila Page
2cfc386773 Convert simple copy. (#7205)
* Convert simple copy.

* Adjust class names for import.

* adjust test namespacing

* Resolve test error.

---------

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2023-03-22 15:53:07 -07:00
Gerda Shank
ae485f996a CT 1998 use google protobuf to enable more flexible dictionaries (#7190) 2023-03-22 15:59:50 -04:00
Peter Webb
73ff497200 ct-2198: Unify constraints and check_constraints fields (#7130)
* ct-2198: clean up some type names and uses

* CT-2198: Unify constraints and constraints_check properties on columns

* Make mypy version consistently 0.981 (#7134)

* CT 1808 diff based partial parsing (#6873)

* model contracts on models materialized as views (#7120)

* first pass

* rename tests

* fix failing test

* changelog

* fix functional test

* Update core/dbt/parser/base.py

* Update core/dbt/parser/schemas.py

* Create method for env var deprecation (#7086)

* update to allow adapters to change model name resolution in py models (#7115)

* update to allow adapters to change model name resolution in py models

* add changie

* fix newline adds

* move quoting into macro

* use single quotes

* add env DBT_PROJECT_DIR support #6078 (#6659)

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>

* Add new index.html and changelog yaml files from dbt-docs (#7141)

* Make version configs optional (#7060)

* [CT-1584] New top level commands: interactive compile (#7008)

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>

* CT-2198: Add changelog entry

* CT-2198: Fix tests which broke after merge

* CT-2198: Add explicit validation of constraint types w/ unit test

* CT-2198: Move access property, per code review

* CT-2198: Remove a redundant macro

* CT-1298: Rework constraints to be adapter-generated in Python code

* CT-2198: Clarify function name per review

---------

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
Co-authored-by: Stu Kilgore <stu.kilgore@dbtlabs.com>
Co-authored-by: colin-rogers-dbt <111200756+colin-rogers-dbt@users.noreply.github.com>
Co-authored-by: Leo Schick <67712864+leo-schick@users.noreply.github.com>
Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: FishtownBuildBot <77737458+FishtownBuildBot@users.noreply.github.com>
Co-authored-by: dave-connors-3 <73915542+dave-connors-3@users.noreply.github.com>
Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-03-22 13:08:06 -04:00
Quigley Malcolm
9a7305d43f CT-2049: Add CommandCompleted event (#7180)
* add protobuf message/class for new CommandCompleted event

For [CT-2049](https://github.com/dbt-labs/dbt-core/issues/6878) we
concluded that we wanted a new event type, [CommandCompleted](https://github.com/dbt-labs/dbt-core/issues/6878#issuecomment-1419718606)
with [four (4) values](https://github.com/dbt-labs/dbt-core/issues/6878#issuecomment-1426118283):
which command was run, whether the command succeeded, the timestamp
that the command finished, and how long the command took. This commit
adds the new event proto defition, the auto generated proto_types, and
the instantiatable even type.

* begin emitting CommandCompleted event in the preflight decorator

The [preflight decorator](4186f99b74/core/dbt/cli/requires.py (L19))
runs at the start of every CLI invocation. Thus is a perfect candidate
for emitting the CommandCompleted event. This is noted in the [dicussion
on CT-2049](https://github.com/dbt-labs/dbt-core/issues/6878#issuecomment-1428643539).

* add CommandCompleted event to event unit tests

* Add: changelog entry

* fire CommandCompleted event reguardless of upstream exceptions

Previously, if `--fail-fast` was specified and an issue was run into
or an unhandled issue became an exception, the CommandCompleted event
would not get fired because at this point in the stack we'd be in
exception thrown handling mode. If an exception does reach this point,
we want to still fire the event and also continue to propogate the
exception. Hence the bare `raise` exists to reraise the caught exception

* Update CommandCompleted event to be a `Debug` level event

We don't actually "always" need this event to be logged. Thus we've
updated it to `Debug` level. [Discussion Context](https://github.com/dbt-labs/dbt-core/pull/7180#discussion_r1139281963)
2023-03-22 08:45:11 -07:00
Emily Rockman
ca23148908 Stop ignoring test directory for precommit (#7201)
* reformat test directory to pass formatting checks

* remove test comment
2023-03-22 08:04:13 -05:00
Jeremy Cohen
8225a009b5 Add deprecation warnings for log-path, target-path in dbt_project.yml (#7185)
* Add deprecation warnings for log-path, target-path in dbt_project.yml

* Fix tests/unit/test_events

* Fix failing tests

* PR feedback
2023-03-21 22:31:15 +01:00
Emily Rockman
9605b76178 update workflow to install dev requirements and remove action deprecations (#7203) 2023-03-21 10:41:33 -05:00
Stu Kilgore
137dd9aa1b Deprecate more env vars (#7175) 2023-03-20 11:51:32 -05:00
Gerda Shank
a203fe866a CT 2196, CT2121 constraints column order (#7161) 2023-03-19 19:24:07 -04:00
FishtownBuildBot
4186f99b74 [Automated] Merged prep-release/1.5.0b4_4438341695 into target main during release process 2023-03-16 10:30:09 -05:00
Github Build Bot
6db899eddd Bumping version to 1.5.0b4 and generate changelog 2023-03-16 14:52:41 +00:00
dependabot[bot]
8ea20b4ba2 Update pathspec requirement from <0.11,>=0.9 to >=0.9,<0.12 in /core (#6737)
* Update pathspec requirement from <0.11,>=0.9 to >=0.9,<0.12 in /core

Updates the requirements on [pathspec](https://github.com/cpburnz/python-pathspec) to permit the latest version.
- [Release notes](https://github.com/cpburnz/python-pathspec/releases)
- [Changelog](https://github.com/cpburnz/python-pathspec/blob/master/CHANGES.rst)
- [Commits](https://github.com/cpburnz/python-pathspec/compare/v0.9.0...v0.11.0)

---
updated-dependencies:
- dependency-name: pathspec
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2023-03-16 10:24:04 -04:00
FishtownBuildBot
3f76f82c88 Add new index.html and changelog yaml files from dbt-docs (#7174) 2023-03-15 12:21:01 -05:00
dependabot[bot]
6cbf66db58 Bump python from 3.10.7-slim-bullseye to 3.11.1-slim-bullseye in /docker (#6424)
* Bump python from 3.10.7-slim-bullseye to 3.11.1-slim-bullseye in /docker

Bumps python from 3.10.7-slim-bullseye to 3.11.1-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-03-14 23:05:25 -04:00
dependabot[bot]
8cd11b380f Bump black from 22.10.0 to 22.12.0 (#6425)
* Bump black from 22.10.0 to 22.12.0

Bumps [black](https://github.com/psf/black) from 22.10.0 to 22.12.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/22.10.0...22.12.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-03-14 23:04:11 -04:00
Emily Rockman
814eb65d59 Support contract config outside model yaml (#7148)
* first pass

* next pass

* works on local project

* fix tests

* changelog

* remove comment

* update error message

* format message

* update tests
2023-03-14 10:19:14 -05:00
Emily Rockman
f24452a3ab use timezone with no DST in test (#7159) 2023-03-13 12:34:14 -05:00
Kshitij Aranke
30503697f2 [CT-1584] New top level commands: interactive compile (#7008)
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-03-10 17:58:33 -08:00
dave-connors-3
90902689c3 Make version configs optional (#7060) 2023-03-10 10:32:29 -05:00
FishtownBuildBot
5a0e776cff Add new index.html and changelog yaml files from dbt-docs (#7141) 2023-03-09 17:23:38 -08:00
Leo Schick
9368e7a6a1 add env DBT_PROJECT_DIR support #6078 (#6659)
Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2023-03-09 10:41:52 -08:00
colin-rogers-dbt
c02ddf8c0e update to allow adapters to change model name resolution in py models (#7115)
* update to allow adapters to change model name resolution in py models

* add changie

* fix newline adds

* move quoting into macro

* use single quotes
2023-03-08 15:33:32 -08:00
Stu Kilgore
64b8a12a42 Create method for env var deprecation (#7086) 2023-03-08 11:07:44 -06:00
Emily Rockman
e895fe9e4b model contracts on models materialized as views (#7120)
* first pass

* rename tests

* fix failing test

* changelog

* fix functional test

* Update core/dbt/parser/base.py

* Update core/dbt/parser/schemas.py
2023-03-07 16:27:25 -06:00
Gerda Shank
8d987521dd CT 1808 diff based partial parsing (#6873) 2023-03-07 16:37:38 -05:00
Gerda Shank
4aafc5ef4a Make mypy version consistently 0.981 (#7134) 2023-03-07 15:12:01 -05:00
Alexander Butler
24ca76ea58 [Feature] Add unix-style fqn wildcard selector method (#6599)
resolves https://github.com/dbt-labs/dbt-core/issues/6598
2023-03-05 06:36:17 -08:00
Michelle Ark
b681908ee2 get_column_schema_from_query macro (#6986)
Add adapter.get_column_schema_from_query
2023-03-03 14:21:22 -05:00
FishtownBuildBot
72076b3fe5 [Automated] Merged prep-release/1.5.0b3_4316612471 into target main during release process 2023-03-02 12:02:33 -06:00
Github Build Bot
0683c59dcd Bumping version to 1.5.0b3 and generate changelog 2023-03-02 17:31:25 +00:00
Stu Kilgore
8019498f09 Remove cli doc generation workflow (#7089) 2023-03-01 10:59:39 -06:00
FishtownBuildBot
6234aec7d2 [Automated] Merged prep-release/1.5.0b2_4298598835 into target main during release process 2023-02-28 18:43:05 -06:00
Github Build Bot
edd8059eb3 Bumping version to 1.5.0b2 and generate changelog 2023-03-01 00:14:39 +00:00
Jeremy Cohen
e3be347768 Roadmap update (Feb 2023) (#7091)
* Init roadmap

* Rework the top paragraph

* Clean-up the whole thing

* Typos and stuff

* Add a missing word

* Fix typo

* Update "when" note

* Next draft

* Propose rename

* Resolve TODOs, still needs a reread

* Being cute

* Another read through

* Fix sentence fragment

---------

Co-authored-by: Florian Eiden <florian.eiden@dbtlabs.com>
2023-02-28 18:48:29 -05:00
FishtownBuildBot
597acf1fa1 Add new index.html and changelog yaml files from dbt-docs (#7092) 2023-02-28 16:11:37 -06:00
Gerda Shank
effa1a0813 Move check of invalid groups earlier in parsing (#7090) 2023-02-28 17:05:20 -05:00
Stu Kilgore
726800be57 Make output_keys param MultiOption (#7068) 2023-02-28 09:29:58 -06:00
Sam Debruyn
8b79747908 fix: add pytz dependency (#7077) 2023-02-28 08:05:28 -06:00
Gerda Shank
ec5d31de0e CT 1993 handle invalid access to private models (#7069) 2023-02-27 17:33:47 -05:00
Emily Rockman
5d61ebbfdb add group for selection logic (#7047)
* add group for selection logic

* changelog

* add more tests

* Update .changes/unreleased/Features-20230224-134533.yaml

* fix broken tests
2023-02-27 15:27:12 -06:00
Gerda Shank
0ef9931d19 CT 1990 add access property to parsed nodes (#7007)
Update manifest schema to version 9
2023-02-24 17:13:09 -05:00
Peter Webb
a2213abbc0 Paw/ct 1844 log params take 2 (#6994)
* CT-1844: Add flags and flag-interaciton tests for more granular log control.

* CT-1844: Apply parameter settings to log configuration

* CT-1844: Fixes per testing

* CT-1844: Type annotation fix.

* Add generated CLI API docs

* CT-1844: Add changelog entry.

* Add generated CLI API docs

* CT-1844: Add new logging parameters to UserConfig

* Add generated CLI API docs

* CT-1844: Code review fixes

* Add generated CLI API docs

---------

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-02-24 09:18:14 -05:00
Jeremy Cohen
915585c36e Fix regression in semver comparison logic (#7040) 2023-02-23 15:47:22 -08:00
Michelle Ark
5ddd40885e parse group config on groupable nodes (#6965)
parse group config on groupable nodes
2023-02-23 14:17:32 -05:00
Gerda Shank
58d1bccd26 Rename "constraints_enabled" to "contract" (#7002)
* Rename "constraints_enabled" to "contract"

* Changie
2023-02-23 12:16:06 -05:00
Gerda Shank
70c26f5c74 CT 2057 Fix compilation logic for ephemeral nodes (#7023)
* Don't overwrite sql in extra_ctes when compiling (rendering) nodes
2023-02-22 17:24:10 -05:00
dependabot[bot]
ac962a4a31 Bump mypy from 0.971 to 0.981 (#5937)
* Bump mypy from 0.971 to 0.981

Bumps [mypy](https://github.com/python/mypy) from 0.971 to 0.981.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.971...v0.981)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

* add type to self

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2023-02-22 10:26:55 -06:00
Chenyu Li
bb2d062cc5 remove old pass through method (#7019) 2023-02-21 13:44:11 -08:00
José Duarte
7667784985 Remove trailing slashes from source paths (#6102) (#6179)
* Remove trailing slashes from source paths (#6102)

* Run changie

* Handle mypy complaints

* Revert format
2023-02-21 10:50:00 -06:00
Emily Rockman
05ecfbcc3a rename workflow to match other files (#7000) 2023-02-21 09:40:27 -06:00
Emily Rockman
e06ae97068 fix regex for completeness (#7014) 2023-02-21 08:32:13 -06:00
FishtownBuildBot
ed50877c4f Add new index.html and changelog yaml files from dbt-docs (#7015) 2023-02-20 16:25:14 -06:00
Brice Loustau
6b5e38ee28 Made project version optional (default None) (#6718)
* Made project version optional (default None)

* Changie

* Removed version from fixture dbt_project_yml

* Linting
2023-02-20 08:40:08 -06:00
Jeremy Cohen
63a1bf9adb Update comment for build_manifest_state_check (#7004) 2023-02-19 17:45:59 +01:00
FishtownBuildBot
2c7238fbb4 [Automated] Merged prep-release/1.5.0b1_4206349891 into target main during release process 2023-02-17 12:39:27 -06:00
colin-rogers-dbt
b1d597109f move hook tests to adapter zone (#6952)
* move hook tests to adapter zone

* test update to sql

* fix fixtures

* Add generated CLI API docs

* remove port

* fix column name

* fix missing "host" in profile

* fixture fix

* fixture fix

* fixture/test fix

* Add generated CLI API docs

* fix fixtures

* remove host assumption from test_run_hooks.py

* undo bumpversion.cfg change

* clean up string interpolation and get method

---------

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-02-17 10:35:21 -08:00
Github Build Bot
7617eece3a Bumping version to 1.5.0b1 and generate changelog 2023-02-17 18:08:59 +00:00
Gerda Shank
8ce92b56d7 CT 2026 test proto serialization of logging events (#6995)
* Fix unit test, functional tests, update structured logging schema check

* Changie

* Remove unneeded cast_to_str
2023-02-17 13:02:51 -05:00
FishtownBuildBot
21fae1c4a4 Add new index.html and changelog yaml files from dbt-docs (#7001) 2023-02-17 09:03:53 -07:00
Chenyu Li
c952d44ec5 fix small issues with flags and logger to support dbt-rpc (#6990) 2023-02-16 16:58:12 -08:00
Doug Beatty
971b38c26b Use IEC standard abbreviations (GiB, TiB, etc) (#6742)
* Use IEC standard abbreviations (GiB, TiB, etc)

* Fix failing test cases

* Remove  accidentally left behind BigQuery-specific methods

* Changelog entry
2023-02-16 14:14:19 -07:00
Michelle Ark
b7884facbf parse group resource (#6921)
parse group resource
2023-02-15 16:49:47 -05:00
Callum McCann
57ce461067 Fixing exposure error (#6934)
* fixing exposure error message

* adding changie
2023-02-15 14:00:20 -06:00
Kshitij Aranke
b1b830643e Revert "Hoist dbt.cli.main into dbt.main namespace (#6939)" (#6987) 2023-02-15 10:11:09 -08:00
Niels Pardon
3cee9d16fa Make use of hashlib.md5() FIPS compliant (#6982)
Signed-off-by: Niels Pardon <par@zurich.ibm.com>
2023-02-15 11:22:25 -05:00
Sung Won Chung
c647706ac2 dbt Constraints / model contracts (#6271)
* start off the blueprints

* test commit

* working snowflake env

* update manifest expectation

* add error handling

* clean up language

* constraints validator

* cleaner example

* better terminal output

* add python error handling

* add to manifest schema

* add to schema config

* clean up comments

* backwards compatible nodeconfig

* remove comments

* clean up more comments

* add changelog

* clarify error message

* constraints list type

* fix grammar

* add global macros

* clearer compile error

* remove comments

* fix tests in this file

* conditional compile errors

* add conditional check in ddl

* add macro to dispatch

* fix regressions in parsed

* fix regressions in manifest tests

* fix manifest test regressions

* fix test_list regressions

* concise data_type terminal error

* remove placeholder function

* fix failed regressions finally

* Revert "Merge branch 'main' of https://github.com/dbt-labs/dbt into dbt-constraints"

This reverts commit 92d2ea7ff5, reversing
changes made to 5d59cc17bc.

* Revert "Revert "Merge branch 'main' of https://github.com/dbt-labs/dbt into dbt-constraints""

This reverts commit 4f747b0bc0.

* remove tmp.csv

* template test plans

* postgres columns spec macro

* schema does not exist error handling

* update postgres adapter

* remove comments

* first passing test

* fix postgres macro

* add more passing tests

* Add generated CLI API docs

* add disabled config test

* column configs match

* test python error handling

* adjust macro with rollback

* start postgres tests

* remove begin commit

* remove begin commit comments

* passing expected compiled sql test

* passing rollback test

* update changelog

* fix artifacts regression

* modularize validator

* PR feedback

* verify database error occurs

* focus on generic outcomes

* fix global macro

* rename to constraints_check

* missed a check rename

* validate at parse time

* raise error for modelparser only

* better spacing in terminal output

* fix test regressions

* fix manifest test regressions

* these are parsing errors now

* fix tests

* test passes in json log format

* add column compile error handling

* update global macros for column handling

* remove TODO

* uppercase columns for consistency

* more specific error handling

* migrate tests

* clean up core tests

* Update core/dbt/include/global_project/macros/materializations/models/table/columns_spec_ddl.sql

For whitespace control in the dbt.log file!

Co-authored-by: dave-connors-3 <73915542+dave-connors-3@users.noreply.github.com>

* Revert "Update core/dbt/include/global_project/macros/materializations/models/table/columns_spec_ddl.sql
"

This reverts commit 59b02980dc.

* update for pre-commit hooks

* update for black formatter

* update for black formatter on all files

* Refactor functional tests

* Fixup formatting

* Dave feedback

* another one - dave

* the hits keep coming

* adjust whitespace

* Light touchup

* Add more flexibility for spark

* Nearly there for spark

* Try regenerating docs

---------

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: dave-connors-3 <73915542+dave-connors-3@users.noreply.github.com>
Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Dave Connors <dave.connors@fishtownanalytics.com>
2023-02-15 16:50:39 +01:00
Emily Rockman
7b33ffb1bd point at main (#6973) 2023-02-14 14:17:28 -06:00
Chenyu Li
f38cbc4feb add helper function for load project/profile (#6964) 2023-02-14 08:47:43 -08:00
Gerda Shank
480e0e55c5 Set relation_name in tests at compile time (#6949) 2023-02-14 11:32:27 -05:00
Michelle Ark
e5c468bb93 dbt_project.yml log-path respects project directory (#6908)
dbt_project.yml log-path respects project directory
2023-02-14 11:30:11 -05:00
Emily Rockman
605c72e86e Automate cutting new .latest branches (#6854)
* first pass

* WIP

* add notes/stubs on more pieces

* more work

* more cleanup

* cleanup

* add more cleanup and generalization

* update to use reusable workflow

* add TODO
2023-02-14 08:09:16 -06:00
Emily Rockman
aad46ac5a8 Changelog Cleanup from feature branch merge (#6935)
* remove changelogs from 1.4

* remove yaml files for already released changes
2023-02-14 08:08:50 -06:00
Emily Rockman
d85618ef26 remove +nightly from version parsing (#6966)
* remove  from version parsing

* update comment

* undo partial version bump
2023-02-14 08:04:26 -06:00
Jeremy Cohen
1250f23c44 Fix petits logging regressions from feature/click-cli merge (#6940)
* Add back initialization events

* Fix log_cache_events. Default stdout logger knows less than it used to

* Add back exception handling events

* Revert "Add back exception handling events"

This reverts commit 26f22d91b660f51f0df6a59f9e5cae16b0ee6fe5.

* Add changelog entry

* Fix test by stringifying dict values

* Add generated CLI API docs

---------

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-02-14 10:48:56 +01:00
Gerda Shank
daea7d59a7 CT 1921 add missing nodes to previous state test (#6961)
* Update WritableManifest.disabled to include metrics and exposures in disabled dictionary
2023-02-13 21:02:20 -05:00
Emily Rockman
4575757c2a remove '+nightly' from release test version (#6907)
* remove '+nightly' from release test version

* fix release branch variable name

* remove comment
2023-02-13 19:41:34 -06:00
Emily Rockman
d7a2f77705 Infer core team membership in changie (#6420)
* part 1 of env var for core team

* add logic to use env vars to generate changelog

* modify version bump to add members via env var

* pull in main and tweak

* add token

* changes for testing

* split step

* remove leading slash

* add version check

* more debugging

* try curl

* try more things

* try more things

* chnage auth

* put back token

* update permissions

* add back fishtown pat

* use new pat

* fix typo

* swap token

* comment out list teams

* change url

* debug path

* add continue

* change core case

* more tweaks

* send output to file

* add file view

* make array

* tweak

* remove []

* add quotes

* add tojson

* add quotes to set

* tweak

* fix id

* tweaks

* more

* more

* remove new lines

* more tweaks

* update to generate changelog

* remove debugging bits

* use central version-bump

* use correct author list

* testing with changelog team automation

* add new token to input

* move secret

* remove testing aspects from workflow

* clean up team logic

* explicitly send secret

* move bumpversion comment

* move comments

* point workflow back tp main

* point to branch for testing

* point back to main

* inherit secrets
2023-02-13 14:08:49 -06:00
Kshitij Aranke
4a4b89606b Hoist dbt.cli.main into dbt.main namespace (#6939) 2023-02-13 12:06:28 -08:00
Michelle Ark
1ebe2e7118 ExposureOwner: Rename to Owner, accept additional fields, require one of 'name' or 'email' (#6912)
update ExposureOwner to require one of email/name, allow additional fields
2023-02-13 10:13:15 -05:00
Gerda Shank
f1087e57bf Fix types.proto and test_events.py (#6947) 2023-02-10 16:31:34 -05:00
Michelle Ark
250537ba58 handle_and_check in main.py (#6941)
handle_and_check in cli/main.py
2023-02-10 15:39:31 -05:00
Peter Webb
ccc7222868 CT-2079: Re-apply accidentally reverted logging fix (#6937) 2023-02-10 14:40:57 -05:00
Chenyu Li
311a57a21e Merge pull request #6931 from dbt-labs/merge_feature_click_cli_main
Merge feature/click-cli into main

Co-authored-by: Ian Knox <ian.knox@dbtlabs.com >
Co-authored-by: Stu Kilgore <stu.kilgore@dbtlabs.com>
Co-authored-by: Michelle Ark <michelle.ark@dbtlabs.com >
Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com >
Co-authored-by: Jeremy Cohen <jeremey@dbtlabs.com >
2023-02-09 18:03:04 -08:00
Chenyu Li
b7c45de6b1 remove old test 2023-02-09 15:55:24 -08:00
Chenyu Li
c53c3cf181 remove old main 2023-02-09 15:53:37 -08:00
Chenyu Li
a77d325c8a fix all tests 2023-02-09 15:51:42 -08:00
Kshitij Aranke
dd41384d82 revert core.dbt.contracts back to code from main 2023-02-09 15:32:34 -08:00
Github Build Bot
aa55fb2d30 Add generated CLI API docs 2023-02-09 22:59:54 +00:00
Kshitij Aranke
864f4efb8b Merge feature/click-cli into main 2023-02-09 14:57:10 -08:00
dependabot[bot]
83c5a8c24b Bump ubuntu from 22.04 to 23.04 (#6865)
* Bump ubuntu from 22.04 to 23.04

Bumps ubuntu from 22.04 to 23.04.

---
updated-dependencies:
- dependency-name: ubuntu
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-02-09 16:59:25 -05:00
Kshitij Aranke
57aef33fb3 Click cli main merge (#6926) 2023-02-09 12:21:39 -08:00
FishtownBuildBot
6d78e5e640 Add most recent dbt-docs changes (#6923)
* Add new index.html and changelog yaml files from dbt-docs

* Update .changes/unreleased/Docs-20230209-082901.yaml

---------

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2023-02-09 13:23:12 -06:00
Ryan Harris
f54a876f65 Update link to dbt install docs (#6883)
* update dbt install link

* add changelog entry
2023-02-09 09:35:33 -08:00
Kshitij Aranke
8bbae7926b Fix Project Env Var Tests (#6916)
Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Ian Knox <ian.knox@dbtlabs.com>
2023-02-09 08:53:39 -08:00
Jeremy Cohen
db2b12021e Fix test_builtin_invocation_args_dict_function (#6898)
Co-authored-by: Ian Knox <ian.knox@dbtlabs.com>
2023-02-09 09:53:42 -06:00
Peter Webb
8b2c9bf39d Ensure flush() after logging write() (#6909)
* ct-2063: Ensure flush after logging, by using Python's logging subsystem directly

* ct-2063: Add changelog entry
2023-02-09 09:37:37 -05:00
Jeremy Cohen
298bf8a1d4 Add back depends_on for seeds - only macros, never nodes (#6851)
* Extend functional tests for seeds w hooks

* Add MacroDependsOn to seeds, raise exception for other deps

* Add changelog entry

* Fix unit tests

* Update upgrade_seed_content

* Cleanup

* Regen manifest v8 schema. Fix tests

* Be less magical

* PR feedback
2023-02-09 10:56:12 +01:00
Michelle Ark
77748571b4 profiles dir exists=False for dbt debug (#6910)
profiles dir exists=False for dbt debug
2023-02-08 18:32:06 -05:00
Stu Kilgore
8ce4c289c5 Docs generate doesn't write manifest (#6905) 2023-02-08 16:16:31 -06:00
Emily Rockman
abbece8876 1.4 regression: Check if status has node attribute (#6899)
* check for node

* add changelog

* add test for regression
2023-02-08 13:49:24 -06:00
dave-connors-3
3ad40372e6 add base class for merge exclude tests (#6700)
* add base class for merge exclude tests

* changie <33

* remove comments

* add comments to sql, remove and clarify contents of resultholder
2023-02-08 10:20:13 -08:00
Kshitij Aranke
c6d0e7c926 Fix Click CLI test DB Name (#6895) 2023-02-08 09:58:16 -08:00
Michelle Ark
bc015843d4 use UnsetProfile in deps and clean commands (#6890)
use unset_profile in deps and clean commands
2023-02-08 12:26:58 -05:00
Emily Rockman
df64511feb Dynamically list all .latest branches for scheduled testing (#6682)
* first pass at automating latest branches

* checkout repo first

* fetch all history

* reorg

* debugging

* update test id

* swap lines

* incorporate new branch aciton

* tweak vars
2023-02-08 08:02:21 -06:00
Michelle Ark
db0981afe7 NoneConfig for DebugTask (#6893)
NoneConfig for DebugTask
2023-02-07 21:33:15 -05:00
Michelle Ark
dcf6544f93 flags.THREADS defaults to None (#6887)
flags.THREADS defaults to None
2023-02-07 17:15:26 -05:00
Ian Knox
c2c8959fee Merge main to feature (#6817)
merge main to feature/click-cli
2023-02-07 16:32:31 -05:00
Peter Webb
ccb4fa26cd CT-1917: Fix a regression in the behavior of the -q/--quiet cli parameter (#6886) 2023-02-07 16:15:42 -05:00
Chenyu Li
d0b5d752df consolidate flags (#6788)
Co-authored-by: Michelle Ark <michelle.ark@dbtlabs.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-02-07 08:35:35 -08:00
Neelesh Salian
4c63b630de [CT-1959]: moving simple_seed tests to adapter zone (#6859)
* Formatting

* Changelog entry

* Rename to BaseSimpleSeedColumnOverride

* Better error handling

* Update test to include the BOM test

* Cleanup and formating

* Unused import remove

* nit line

* Pr comments
2023-02-06 19:51:32 -08:00
Kshitij Aranke
9c0b62b4f5 Fix CLI vars test to check for object instead of string (#6850) 2023-02-06 15:13:40 -08:00
Ian Knox
e08eede5e2 Remove unused cli_runner (#6877) 2023-02-06 15:24:09 -06:00
Ian Knox
05e53d4143 Test fix: TestProfileEnvVars::test_profile_env_vars (#6856) 2023-02-06 10:49:40 -06:00
colin-rogers-dbt
b2ea2b8b25 move test_store_test_failures.py to adapter zone (#6816) 2023-02-02 10:55:09 -08:00
Emily Rockman
2245d8d710 update regex to match all iterations (#6839)
* update regex to match all iterations

* convert to num to match all adapters

* add comments, remove extra .

* clarify with more comments

* Update .bumpversion.cfg

Co-authored-by: Nathaniel May <nathaniel.may@fishtownanalytics.com>

---------

Co-authored-by: Nathaniel May <nathaniel.may@fishtownanalytics.com>
2023-02-02 12:16:06 -06:00
Gerda Shank
d9424cc710 CT 2000 fix semver prerelease comparisons (#6838)
* Modify semver.py to not use packaging.version.parse

* Changie
2023-02-02 12:22:48 -05:00
Stu Kilgore
0503c141b7 Lazily call --version (#6813)
* Lazily call --version

* Add generated CLI API docs

---------

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-01-31 17:20:18 -08:00
Mila Page
1a6e4a00c7 Add clearer directions for custom test suite vars in Makefile. (#6764)
* Add clearer directions for custom test suite vars in Makefile.

* Fix up PR for review

* Fix erroneous whitespace.

* Fix a spelling error.

* Add documentation to discourage makefile edits but provide override tooling.

* Fix quotation marks. Very strange behavior

* Compact code and verify quotations happy inside bash and python.

* Fold comments into Makefile.

---------

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2023-01-31 13:53:55 -08:00
Mila Page
42b7caae19 Ct 1827/064 column comments tests conversion (#6766)
* Convert test and make it a bit more pytest-onic

* Ax old integration test.

* Run black on test conversion

* I didn't like how pytest was running the fixture so wrapped it into a closure.

* Merge converted test into persist docs.

* Move persist docs tests to the adapter zone. Prep for adapter tests.

* Fix up test names

* Fix name to be less confusing.

---------

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2023-01-31 12:58:19 -08:00
Emily Rockman
622e5fd71d fix contributor list generation (#6799) 2023-01-31 13:05:13 -06:00
Stu Kilgore
59d773ea7e Implement --version in click (#6802) 2023-01-31 12:40:01 -06:00
Kshitij Aranke
84bf5b4620 [CT-1947] Alias --models to --select for all commands except dbt ls (#6787)
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-01-31 10:18:10 -08:00
Ian Knox
726c4d6c58 Enable the new Click Cli (#6785) 2023-01-30 19:30:01 -06:00
Michelle Ark
acc88d47a3 mutually exclusive handling for warn_error_options and warn_error params in Click CLI (#6771)
warn_error_options, warn_error mutual exclusivity with click
2023-01-30 18:38:36 -05:00
Chenyu Li
0a74594d09 move favor state arg to click (#6774) 2023-01-30 11:55:31 -08:00
Kshitij Aranke
d2f3cdd6de [CT-1841] Convert custom target test to Pytest (#6765) 2023-01-30 07:55:28 -08:00
Alexander Smolyakov
92d1ef8482 Update release workflow (#6778)
- Update AWS secrets
- Rework condition for Slack notification
2023-01-30 09:19:10 -06:00
Neelesh Salian
a8abc49632 [CT-1940] Stand-alone Python module for PostgresColumn (#6773) 2023-01-27 17:00:39 -08:00
Ian Knox
d6ac340df0 Merge main into feature/click-cli (#6761) 2023-01-27 15:07:30 -06:00
Neelesh Salian
c653330911 Adding nssalian to committers list (#6769) 2023-01-27 11:16:59 -08:00
Alexander Smolyakov
82d9b2fa87 [CI/CD] Update release workflow and introduce workflow for nightly releases (#6602)
* Add release workflows

* Update nightly-release.yml

* Set default `test_run` value to `true`

* Update .bumpversion.cfg

* Resolve review comment

- Update workflow docs
- Change workflow name
- Set `test_run` default value to `true`

* Update Slack secret

* PyPI
2023-01-27 09:04:31 -06:00
Mila Page
3f96fad4f9 Ct 1629/052 column quoting tests conversion (#6652)
* Test converted and reformatted for pytest.

* Ax old versions of 052 test

* Nix the 'os' import and black format

* Change names of models to be more PEP like

* cleanup code

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2023-01-26 12:23:02 -08:00
Peter Webb
c2c4757a2b Graph Analysis Optimization for Large Dags (#6720)
* Optimization to remove graph analysis bottleneck in large dags.

* Add changelog entry.
2023-01-26 14:27:42 -05:00
Kshitij Aranke
08b2d94ccd [CT-920][CT-1900] Create Click CLI runner and use it to fix dbt docs … (#6723)
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-01-26 10:42:49 -08:00
Michelle Ark
7fa61f0816 dbt init works with click (#6698)
dbt init works with click
2023-01-26 12:45:15 -05:00
Mila Page
c65ba11ae6 Ct 1827/064 column comments tests conversion (#6654)
* Convert test and make it a bit more pytest-onic

* Ax old integration test.

* Run black on test conversion

* I didn't like how pytest was running the fixture so wrapped it into a closure.

* Merge converted test into persist docs.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2023-01-26 00:54:00 -08:00
Matthew Beall
b0651b13b5 change exposure_content to source_content (#6739)
* change `exposure_content` to `source_content`

* Adding changelog

Co-authored-by: Leah Antkiewicz <leah.antkiewicz@fishtownanalytics.com>
2023-01-25 19:51:34 -05:00
Gerda Shank
a34521ec07 CT 1894 log partial parsing var changes and sort cli vars before hashing (#6713)
* Log information about vars_hash, normalize cli_vars before hashing

* Changie

* Add to test_events.py

* Update core/dbt/events/types.py

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2023-01-25 17:47:45 -05:00
Matthew McKnight
da47b90503 [CT-1630] Convert Column_types tests (#6690)
* init commit for column_types test conversion

* init start of test_column_types.py

* pass tes macros into both tests

* remove alt tests, remove old tests, push up working conversion

* rename base class, move to adapter zone so adapters can use

* typo fix
2023-01-25 14:57:16 -06:00
Stu Kilgore
d27016a4e7 Migrate debug task to click (#6728) 2023-01-25 14:52:57 -06:00
Peter Webb
db99e2f68d Event Clean-Up (#6716)
* CT-1857: Event cleanup

* Add changelog entry.
2023-01-25 13:51:52 -05:00
Michelle Ark
cbb9117ab9 test_init conversion (#6610)
* convert 044_init_tests
2023-01-24 16:22:26 -05:00
Gerda Shank
e2ccf011d9 CT 1886 include adapter_response in NodeFinished log message (#6709)
* Include adapter_response in run_result in NodeFinished log event

* Changie
2023-01-24 14:25:32 -05:00
Aezo
17014bfad3 add adapter_response for test (#6645)
resolves https://github.com/dbt-labs/dbt-core/issues/2964
2023-01-24 09:58:08 -08:00
Stu Kilgore
92b7166c10 Abstract manifest generation from tasks (#6565) 2023-01-24 11:05:57 -06:00
Peter Webb
7b464b8a49 CT-1718: Add Note and Formatting event types (#6691)
* CT-1718: Add Note and Formatting event types

* CT-1718: Add changelog entry
2023-01-23 16:39:29 -05:00
Sean McIntyre
5c765bf3e2 Cheeky performance improvement on big DAGs (#6694)
* Short-circuit set operations for nice speed boost

* Add changelog

* Fix issue

* Update .changes/unreleased/Under the Hood-20230122-215235.yaml

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2023-01-23 09:09:09 -07:00
Mila Page
93619a9a37 Ct 738/dbt debug log fix (#6541)
* Code cleanup and adding stderr to capture dbt

* Debug with --log-format json now prints structured logs.

* Add changelog.

* Move logs into miscellaneous and add values to test.

* nix whitespace and fix log levels

* List will now do structured logging when log format set to json.

* Add a quick None check.

* Add a get guard to class check.

* Better null checking

* The boolean doesn't reflect the original logic but a try-catch does.

* Address some code review comments and get us working again.

* Simplify logic now that we have a namespace object for self.config.args.

* Simplify logic for json log format checking.

* Simplify code for allowing our GraphTest cases to pass while also hiding compile stats from dbt ls/list .

* Simplify structured logging types.

* Fix up boolean logic and simplify via De'Morgan.

* Nix unneeded fixture.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2023-01-20 16:37:54 -08:00
Doug Beatty
a181cee6ae Improve error message for packages missing dbt_project.yml (#6685)
* Improve error message for packages missing `dbt_project.yml`

* Use black formatting

* Update capitalization of expected error message
2023-01-20 13:46:36 -07:00
Michelle Ark
a0ade13f5a dbt docs generate works with click (#6681) 2023-01-20 15:26:20 -05:00
Michelle Ark
9823a56e1d dbt build works in click (#6680)
* build working with click
2023-01-20 14:27:39 -05:00
Michelle Ark
3aeab73740 convert 069_build_tests (#6678) 2023-01-20 14:27:02 -05:00
Jeremy Cohen
9801eebc58 Consolidate changie entries from #6620 (#6684) 2023-01-20 19:58:40 +01:00
Jeremy Cohen
11c622230c Add run-operation to click CLI (#5552) (#6656)
* Add run-operation to click CLI

* Add changelog entry

* PR feedback

* Fix unit test
2023-01-20 01:58:47 +01:00
Chenyu Li
f0349488ed Seed and freshness works with click (#6651) 2023-01-19 16:14:26 -08:00
Chenyu Li
c85be323f5 fix MP_CONTEXT is not JSON serializable (#6650) 2023-01-19 08:16:58 -08:00
Peter Webb
6954c4df1b CT-1786: Port docs tests to pytest (#6608)
* CT-1786: Port docs tets to pytest

* Add generated CLI API docs

* CT-1786: Comply with the new style requirements

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-01-19 11:11:17 -05:00
Michelle Ark
30a1595f72 click working with list (#6641)
* list working with click
2023-01-19 09:28:32 -05:00
dave-connors-3
f841a7ca76 add backwards compatibility and default argument for incremental_predicates (#6628)
* add backwards compatibility and default argument

* changie <3

* Update .changes/unreleased/Fixes-20230117-101342.yaml

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2023-01-19 15:20:19 +01:00
Jeremy Cohen
07a004b301 convert 062_defer_state_tests (#6616)
* Fix --favor-state flag

* Convert 062_defer_state_tests

* Revert "Fix --favor-state flag"

This reverts commit ccbdcbad98b26822629364e6fdbd2780db0c20d3.

* Reformat

* Revert "Revert "Fix --favor-state flag""

This reverts commit fa9d2a09d6.
2023-01-19 11:00:09 +01:00
Jeremy Cohen
b05582de39 mv on_schema_change tests -> "adapter zone" (#6618)
* Mv incremental on_schema_change tests to 'adapter zone'

* Use type_string()

* Cleanup
2023-01-19 10:12:59 +01:00
Jeremy Cohen
fa7c4d19f0 Respect quoting config in dbt-py models (#6620)
* Respect quoting for 'this' in dbt-py models #6619

* Respect quoting for ref/source in dbt-py models #6103

* Add changelog entries
2023-01-19 09:34:08 +01:00
Chenyu Li
1913eac5ed Click snapshot as click command (#5972) (#6640) 2023-01-18 16:01:58 -08:00
Jeremy Cohen
066346faa2 convert 038_caching_tests (#6612)
* convert 038_caching_tests

* Adapt for dbt-snowflake

* PR feedback

* Reformat
2023-01-18 22:37:50 +01:00
Emily Rockman
0a03355ceb update test matrix (#6604) 2023-01-18 14:16:34 -06:00
David Bloss
43e24c5ae6 update gh action set-output variables (#6635)
* update gh action set-output variables

* add changie file
2023-01-18 11:23:13 -06:00
Gerda Shank
89d111a5f6 CT 1440 Fix code to emit ConnectionReused event (#6605)
* Refactor "set_connection_name" to properly handle reused connection

* Update test

* Changie

* Limit test of ConnectionUsed events to non-Windows
2023-01-17 13:18:07 -05:00
Gerda Shank
e1b5e68904 Convert 068_partial_parsing_tests (#6614)
* Convert partial parsing tests

* reformat
2023-01-17 12:22:31 -05:00
Jeremy Cohen
065ab2ebc2 Reformat tests/ (#6622)
* Run black + flake8 on tests dir

* Run pre-commit
2023-01-16 16:39:54 +01:00
Michelle Ark
20c95a4993 convert 057_run_query_tests (#6607) 2023-01-13 15:02:17 -05:00
Michelle Ark
c40b488cb4 convert 037_external_references (#6589) 2023-01-13 14:15:03 -05:00
Chenyu Li
585e7c59e8 migrate ref override (#6600) 2023-01-13 09:15:04 -08:00
Michelle Ark
7077c47551 converting 022_test_timezones (#6588) 2023-01-13 10:52:21 -05:00
Chenyu Li
f789b2535a convert adapter table materialization test (#6595) 2023-01-12 16:05:51 -08:00
Emily Rockman
2bfc6917e2 finish message rename in types.proto (#6594)
* finish message rename in types.proto

* add new parameter
2023-01-12 14:33:56 -06:00
github-actions[bot]
d74ae19523 Bumping version to 1.5.0a1 and generate changelog (#6593)
* Bumping version to 1.5.0a1 and generate CHANGELOG

* make relevvant changelog updates

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2023-01-12 12:59:28 -06:00
Michelle Ark
1c7c23ac73 convert 043_custom_alias_tests (#6590) 2023-01-12 11:07:26 -05:00
Jeremy Cohen
86e8722cd8 Call update_event_status earlier + rename an event (#6572)
* Rename HookFinished -> FinishedRunningStats

* Move update_event_status earlier when node finishes

* Add changelog entry

* Add update_event_status for skip

* Update changelog entry
2023-01-12 09:34:36 +01:00
Kshitij Aranke
53127daad8 [CT-921] dbt compile works in click (#5545) (#6586)
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
resolves https://github.com/dbt-labs/dbt-core/issues/5545
2023-01-11 15:01:50 -08:00
Kshitij Aranke
91b20b7482 dbt test works with Click (#5556)
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
resolves https://github.com/dbt-labs/dbt-core/issues/5556
2023-01-11 12:19:43 -08:00
Michelle Ark
7a61602738 Add --warn-error-options (#6520)
* adding --warn-error-options

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-01-10 19:43:52 -05:00
Doug Beatty
dd4b47d8b1 Check length of escaped strings in the adapter test (#6567)
* Check length of escaped strings in the adapter test

* One column per line to improve readability
2023-01-10 17:26:35 -07:00
Emily Rockman
eb200b4687 Rename exceptions (#6539)
* rename InternalException

* rename RuntimeException

* rename DatabaseException

* rename CompilationException

* cleanup renames in tests and postgres

* rename ValidationException

* rename IncompatibleSchemaException

* more renaming

* more renaming

* rename InternalException again

* convert ParsingException

* replace JSONValidationException and SemverException

* replace VersionsNotCompatibleException

* replace NotImplementedException

* replace FailedToConnectException

* replace InvalidConnectionException

* replace InvalidSelectorException

* replace DuplicateYamlKeyException

* replace ConnectionException

* minor cleanup

* update comment

* more cleanup

* add class decorator

* rename more exceptions

* more renamed, add changelog

* rename exception

* rework class deprecations

* removing testing line

* fix failing test

* rename newer exceptions

* fix failing test

* commit unsaved faile

* convert back an rpc exception

* remove class deprecations
2023-01-10 17:43:27 -06:00
mivanicova
0fc080d222 add defer_to_manifest in before_run to fix faulty deferred docs generate (#6488)
* add defer_to_manifest in before_run to fix faulty deferred docs generate

* add a changelog

* add declaration of defer_to_manifest to FreshnessTask and GraphRunnableTask

* fix: add defer_to_manifest method  to ListTask
2023-01-10 15:18:20 -08:00
AGPapa
5da63602b3 Adds buildable selection mode (#6366) 2023-01-10 15:15:48 -08:00
nshuman1
457ff3ef48 fixed minor typos (#6499)
* fixed minor typos

* adding changelog file

* linter

* Update Docs-20230102-170216.yaml
2023-01-10 13:36:21 -08:00
Gerda Shank
0dbdecef10 Ct 1716 cleanup logging events (#6561)
* Combine DbtProfileError log events

* Combine DbtProjectErrorException with DbtProjectError

* Combine cache logging events

* Changie

* fix ticket number

* Ooops. Add another file.

* fix serialization of profile names
2023-01-10 15:56:52 -05:00
Doug Beatty
b13b0e9492 Re-factor list of YAML keys for hooks to late-render (#6435)
* Re-factor list of YAML keys for hooks to late-render

* Add `pre_` and `post_hook` to list of late-rendered hooks

* Check for non-empty set intersection

Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>

* Test functional synonymy of `*_hook` with `*-hook`

Test that `pre_hook`/`post_hook` are functionally synonymous with `pre-hook`/`post-hook` for model project config

* Undo bugfix to validate the new test fails

* Revert "Undo bugfix to validate the new test fails"

This reverts commit e83a2be2eb.

Co-authored-by: Kshitij Aranke <kshitij.aranke@dbtlabs.com>
2023-01-10 12:35:06 -07:00
Tim Mastny
b9fdfd9e36 Adds the meta field to node_info in logs (#6493)
* add meta attribute to nodeinfo for events

* also add meta to dataclass

* add to unit test to ensure meta is added

* adding functional test to check that meta is passed to nodeinfo during logging

* changelog

* remove used imported

* add tests with non-string keys

* renaming test dict keys

* add non-string value

* resolve failing test

* test additional non-string values

* fix flake8

* Stringify meta dict in node_info

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2023-01-10 13:42:51 -05:00
Peter Webb
4d6352db14 CT-1645: Bump mashumaro version to receive regression fix, and add unit test to confirm fix. (#6564) 2023-01-10 13:14:24 -05:00
Doug Beatty
9eb82c6497 Remove duplicated changelog entry for 5521 (#6563) 2023-01-10 11:13:50 -07:00
Jeremy Cohen
89cc89dfdf Fix changelog entry for 5989/6432 (#6560) 2023-01-10 06:57:39 -07:00
Kshitij Aranke
2b0f6597a4 [CT-1694] Deprecate event tracking tests (#6538) 2023-01-09 15:23:02 -08:00
Peter Webb
294def205f Fix event level regression (#6556)
* CT-6501: Make certain disabled test events debug-level again to match historical behavior.

* CT-1740: Add changelog entry.
2023-01-09 18:15:59 -05:00
Emily Rockman
34fa703466 fix log msg format (#6557) 2023-01-09 15:56:42 -06:00
Mila Page
ab3f8dcbfd Ct 1517/convert 060 persist docs (#6409)
* convert the test and fix an error due to a dead code seed

* Get rid of old test

* Remove unfortunately added files. Don't use that *

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2023-01-09 11:07:34 -08:00
Emily Rockman
02c20477b9 add deprecation decorator (#6540)
* add derecation decorator

* fix tests

* updated changelog and deprecation reason
2023-01-09 12:09:12 -06:00
Gerda Shank
d9a4ee126a CT 1549 reorg logging events to have two top level keys (#6553)
* Update types.proto

* pre-commit passes

* Cleanup tests and tweak EventLevels

* Put node_info back on SQLCommit. Add "level" to fire_event function.

* use event.message() in warn_or_error

* Fix logging test

* Changie

* Fix a couple of unit tests

* import Protocol from typing_extensions for 3.7
2023-01-09 11:33:44 -05: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
Kshitij Aranke
94d6d19fb4 [CT-1693] Port severity test to Pytest (#6537) 2023-01-06 11:59:53 -08:00
Callum McCann
d43c070007 Making Metric Timestamps Optional (#6402)
* changing to optional

* adding tests

* tests and changie

* pre-commit cleaning

* formatting fixes

* pre-commit update
2023-01-05 15:49:55 -05:00
Callum McCann
9ef236601b Updating metric attributes renamed event (#6518)
* updating message

* adding changie
2023-01-05 15:49:44 -05:00
justbldwn
9d6f961d2b 🎨 add missing fstrings, convert format to fstring (#6243)
Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2023-01-05 15:28:27 -05:00
Niall Woodward
5453840950 DBT_FAVOR_STATE_STATE -> DBT_FAVOR_STATE (#6392)
* DBT_FAVOR_STATE_STATE -> DBT_FAVOR_STATE

* add changelog
2023-01-04 15:53:35 -08:00
Gerda Shank
d453964546 CT 1551 partial parsing logging events (#6474) 2023-01-04 14:28:26 -05:00
dependabot[bot]
748a932811 Update agate requirement from <1.6.4,>=1.6 to >=1.6,<1.7.1 in /core (#6506)
* Update agate requirement from <1.6.4,>=1.6 to >=1.6,<1.7.1 in /core

Updates the requirements on [agate](https://github.com/wireservice/agate) to permit the latest version.
- [Release notes](https://github.com/wireservice/agate/releases)
- [Changelog](https://github.com/wireservice/agate/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/wireservice/agate/compare/1.6.0...1.7.0)

---
updated-dependencies:
- dependency-name: agate
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2023-01-04 09:02:37 -08:00
Jeremy Cohen
8217ad4722 Fix issue link for 5859 changelog entry (#6496) 2023-01-04 10:46:52 +01: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
Gerda Shank
6ef3fbbf76 Partial parsing bug with empty schema file - ensure None is not passed to load_yaml_text (#6494) 2023-01-03 17:14:56 -05:00
justbldwn
76fd12c7cd adding pre-commit install to make dev (#6417)
*  adding pre-commit install to make dev

* 🎨 updating format of Makefile and CONTRIBUTING.md

* 📝 adding changelog via changie new

*  adding dev_req to Makefile + docs

* 🎨 remove dev_req from docs, dry makefile

* Align names of `.PHONY` targets with their associated rules

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
Co-authored-by: Doug Beatty <doug.beatty@dbtlabs.com>
2023-01-03 11:18:55 -07:00
Doug Beatty
9ecb6e50e4 Treat dense text blobs as binary for git grep (#6462) 2022-12-20 17:10:01 -07:00
Kshitij Aranke
ce9d0afb8a [CT-1591] Don't parse empty Python files (#6433) 2022-12-20 10:56:36 -08:00
Emily Rockman
c39ea807e8 add back validator_error_message (#6465) 2022-12-20 10:56:08 -06:00
Ikko Ashimine
1e35339389 Fix typo in util.py (#6037)
* Fix typo in util.py

identifer -> identifier

* Add change log

* Update .changes/unreleased/Fixes-20221117-220320.yaml

Co-authored-by: Emily Rockman <ebuschang@gmail.com>
2022-12-19 20:01:19 -06:00
Emily Rockman
304797b099 exception cleanup (#6347)
* starting to move jinja exceptions

* convert some exceptions

* add back old functions for backward compatibility

* organize

* more conversions

* more conversions

* add changelog

* split out CacheInconsistency

* more conversions

* convert even more

* convert parsingexceptions

* fix tests

* more conversions

* more conversions

* finish converting exception functions

* convert more tests

* standardize to msg

* remove some TODOs

* fix test param and check the rest

* add comment, move exceptions

* add types

* fix type errors

* fix type for adapter_response

* remove 0.13 version from message
2022-12-19 19:36:24 -06:00
Emily Rockman
b9bdb775ab Fix dependency changelog kind (#6452) 2022-12-19 13:13:38 -06: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
leahwicz
df93858b4b Updating 1.4.0b1 changelog (#6450) 2022-12-15 09:55:23 -05:00
dave-connors-3
e8da84fb9e Feature/support incremental predicates (#5702)
* pass predicated to merge strategy

* postgres delete and insert

* merge with predicates

* update to use arbitrary list of predicates, not dictionaries, merge and delete

* changie

* add functional test to adapter zone

* comma in test config

* add test for incremental predicates delete and insert postgres

* update test structure for inheritance

* handle predicates config for backwards compatibility

* test for predicates keyword

* Add generated CLI API docs

Co-authored-by: Colin <colin.rogers@dbtlabs.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-12-14 14:07:41 -08:00
Peter Webb
7e90e067af Paw/ct 1652 restore default logging (#6447)
* CT-1652: Restore stdout logging before logger is fully configured

* CT-1652: Add changelog entry

* CT-1652: formatting fix for black
2022-12-14 17:04:50 -05:00
Peter Webb
5e4e917de5 CT-1685: Restore certain aspects of legacy logging behavior important… (#6443)
* CT-1685: Restore certain aspects of legacy logging behavior important to dbt-rpc

* CT-1658: And changelog entry
2022-12-14 11:13:34 -05:00
github-actions[bot]
05dc0212e7 Bumping version to 1.4.0b1 and generate changelog (#6440)
* Bumping version to 1.4.0b1 and generate CHANGELOG

* Updating date

* Updating date

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-12-13 20:18:11 -05:00
Gerda Shank
c00052cbfb Add Optional back on "database" field of HasRelationMetadata (#6439) 2022-12-13 18:15:25 -05:00
Kshitij Aranke
3d54a83822 [CT-1284] Change Python model default materialization to table (#6432) 2022-12-13 15:07:56 -08:00
Gerda Shank
fafd5edbda CT 1644 node cleanup (#6427)
* Remove unneeded SQL compilation attributes from SeedNode

* Fix various places that referenced removed attributes

* Cleanup a few Unions

* More formatting in nodes.py

* Mypy passing. Untested.

* Unit tests working

* use "doc" in documentation unique_ids

* update some doc_ids

* Fix some artifact tests. Still need previous version.

* Update manifest/v8.json

* Move relation_names to parsing

* Fix a couple of tests

* Update some artifacts. snapshot_seed has wrong schema.

* Changie

* Tweak NodeType.Documentation

* Put store_failures property in the right place

* Fix setting relation_name
2022-12-13 12:39:35 -05:00
Josh Devlin
8478262580 Update docker README (#6423) 2022-12-13 11:12:34 -05:00
Kshitij Aranke
83b1fee062 Add aranke to core committers (#6431) 2022-12-12 15:13:03 -08:00
Emily Rockman
0fbbc896b2 Remove PR from most changelog kinds (#6374)
* update changie to require issue or pr, and allow multiple

* remove extraneous data from changelog files.

* allow for multiple PR/issues to be entered

* update contributing guide

* remove issue number from bot changelogs

* update format of PR

* fix dependency changelogs

* remove extra line

* remove extra lines, tweak contributor wording

* Update CONTRIBUTING.md

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2022-12-12 13:18:15 -06:00
Stu Kilgore
ce1aaec31d Adjust tox passenv to be multiline (#6405) (#6430) 2022-12-12 11:13:04 -06:00
Ian Knox
0544b08543 Add support for Python 3.11 (#6326)
* Get running with Python 3.11

* More tests passing, mypy still unhappy

* Upgrade to 3.11, and bump mashumaro

* patch importlib.import_module last

* lambda: Policy() default_factory on include and quote policy

* Add changelog entry

* Put a lambda on it

* Fix text formatting for log file

* Handle variant type return from e.log_level()

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Josh Taylor <joshuataylorx@gmail.com>
Co-authored-by: Michelle Ark <michelle.ark@dbtlabs.com>
2022-12-08 18:34:03 +01: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
bruno messias
bef6edb942 Fix dbt.config.get default values (python-model) (#6317)
* feat: add a list of default values to the ctx manager

* tests: dbt.get.config default values

* feat: validate the num of args in config.get

* feat: jinja template for dbt.config.get default values

* docs: changie yaml

* fix:typo on error message

Co-authored-by: Chenyu Li <chenyulee777@gmail.com>

Co-authored-by: Chenyu Li <chenyulee777@gmail.com>
2022-12-07 15:52:38 -08:00
timle
99f27de934 Feature/dbt deps tarball (#4689)
* v0 - new dbt deps type: tarball url

in support of
https://github.com/dbt-labs/dbt-core/issues/4205

* flake8 fixes

* adding max size tarball condition

* clean up imports

* typing

* adding sha1 and subdirectory options; improve logging feedback

sha1: allow user to specify sha1 in packages.yaml, will only install if package matches
subdirectory: allow user to specify subdirectory of package in tarfile, if the package is a non standard structure (like with git subdirectory option)

* simple tests added

* flake fixes

* changes to support tests; adding exceptions; fire_event logging

* new logging events

* tarball exceptions added

* build out tests

* removing in memory tarball test

* update type codes to M - Misc

* adding new events to test_events

* fix spacing for flake

* add retry download code - as used in registry calls

* clean

* remove saving tar in memory inside tarfile object

will hit url multiple times instead

* remove duplicative code after refactor

* black updates

* black formatting

* black formatting

* refactor - no more in-memory tarfile - all as file operations now

- remove tarfile passing, always use tempfile instead
- reorganize system.* functions, removing duplicative code
- more notes on current flow and structure - esp need for pattern of 1) unpack 2) scan for package dir 3) copy to destination.
- cleaning

* cleaning and sync to new tarball code

* cleaning and sync to new tarball code

* requested changes from PR

https://github.com/dbt-labs/dbt-core/pull/4689#discussion_r812970847

* reversions from revision 2

removing sha1 check to simplify/mirror hub install pattern

* simplify/mirror hub install pattern

to simplify/mirror hub install pattern
- removing sha1 check
- supply name/version to act as our 'metadata' source

* simplify/mirror hub install pattern

simplify with goal of mirroring hub install pattern
- supporting subfolders like git packages, and sha1 checks are removed
- existing code from RegistryPinnedPackage (install() and download_and_untar()) performs the operations
- RegistryPinnedPackage install() and download_and_untar() are not currently set up as functions that can be used across classes - this should be moved to dbt.deps.base, or to a dbt.deps.common file - need dbt labs feedback on how to proceed (or leave as is)

* remove revisions, no longer doing package check

* slim down to basic tests

more complex features have been removed (sha1, subfolder) so testing is much simpler!

* fix naming to match hubs behavior

remove version from package folder name

* refactor install and download to upstream PinnedPackage class

i'm on the fence if this is right approach, but seems like most sensible after some thought

* Create Features-20221107-105018.yaml

* fix flake, black, mypy errors

* additional flake/black fixes

* Update .changes/unreleased/Features-20221107-105018.yaml

fix username on changelog

Co-authored-by: Emily Rockman <ebuschang@gmail.com>

* change to fstring

Co-authored-by: Emily Rockman <ebuschang@gmail.com>

* cleaning - remove comment

* remove comment/question for dbt team

* in support of issuecomment 1334055944

https://github.com/dbt-labs/dbt-core/pull/4689#issuecomment-1334055944

* in support of issuecomment 1334118433

https://github.com/dbt-labs/dbt-core/pull/4689#issuecomment-1334118433

* black fixes; remove debug bits

* remove `.format` & add 'tarball' as version

'tarball' as version so that the temp files format nicely:
[tempfile_location]/dbt_utils_2..tar.gz # old
vs
[tempfile_location]/dbt_utils_1.tarball.tar.gz # current

* port os.path refs in `PinnedPackage._install` to pathlib

* lowercase as per PR feedback

* update tests after removing version arg

goes along with 8787ba41af

Co-authored-by: Emily Rockman <ebuschang@gmail.com>
2022-12-07 15:48:17 -06:00
Jeremy Cohen
9c91f3a7bd Adjust tox passenv to be multiline (#6405) 2022-12-07 22:47:51 +01:00
Gerda Shank
1b6fed2ffd CT 1604 remove compiled classes (#6384)
* removed Compiled versions of nodes

* Remove compiled fields from dictionary if not compiled

* check compiled is False instead of attribute existence in env_var
processing

* Update artifacts test (CompiledSnapshotNode did not have SnapshotConfig)

* Changie

* more complicated 'compiling' check in env_var

* Update test_exit_codes.py
2022-12-07 15:21:05 -05:00
dependabot[bot]
0721f2c1b7 Bump mashumaro[msgpack] from 3.1.1 to 3.2 in /core (#6375)
* Bump mashumaro[msgpack] from 3.1.1 to 3.2 in /core

Bumps [mashumaro[msgpack]](https://github.com/Fatal1ty/mashumaro) from 3.1.1 to 3.2.
- [Release notes](https://github.com/Fatal1ty/mashumaro/releases)
- [Commits](https://github.com/Fatal1ty/mashumaro/compare/v3.1.1...v3.2)

---
updated-dependencies:
- dependency-name: mashumaro[msgpack]
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-12-07 10:16:31 -05:00
Doug Beatty
b9a35da118 Fix intermittent database connection failure in Windows CI test (#6395)
* Fix intermittent database connection failure in Windows CI test

* Changelog entry
2022-12-06 18:34:39 -07:00
Peter Webb
60f80056b1 CT-1405: Refactor event logging code (#6291)
* CT-1405: Refactor event logging code

* CT-1405: Add changelog entry

* CT-1405: Add code to protect against using closed streams from past tests.

* CT-1405: Restore unit test which was only failing locally

* CT-1405: Document a hack with issue # to resolve it in the future

* CT-1405: Make black happy

* CT-1405: Get rid of confusing factory function and duplicated function

* CT-1405: Remove unused event from types.proto and auto-gen'd file
2022-12-06 15:51:52 -05:00
Stu Kilgore
540c3b79aa Prevent docs gen workflow on forks (#6390) 2022-12-06 11:14:20 -06:00
Stu Kilgore
77be2e4fdf Pin ubuntu at 20.04 for some workflows (#6380) 2022-12-05 10:55:36 -06:00
Gerda Shank
16f529e1d4 CT 1477 enrich logging events with data similar to legacy logger (#6325) 2022-12-02 19:29:25 -05:00
Doug Beatty
ebfcf2a9ef Update core/dbt/README.md to match current (#6371)
* Update core/dbt/README.md to match current

Add missing files/folders and alphabetize

* Changelog entry
2022-12-02 15:45:53 -07:00
Alexander Butler
67a8138b65 [fix] Fix the partial parse write path (#6081)
* Fix the partial parse path

Partial parse should use project root or it does not resolve to correct path. 
Eg. `target-path: ../some/dir/target`, if not ran from root, creates an erroneous folder.

* Run pre-commit

* Changie

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2022-12-02 17:23:37 -05: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
leahwicz
85d0b5afc7 Reverting back to older ubuntu image (#6363)
* Reverting back to older ubuntu image

* Updating the structured logging workflow as well
2022-12-02 12:09:46 -05:00
Matthew McKnight
1fbcaa4484 reformatting of test after some spike investigation (#6314)
* reformatting of test after some spike investigation

* reformat code to pull tests back into base class definition, move a test to more appropriate spot
2022-12-01 16:54:58 -06:00
justbldwn
481235a943 clarify error log for number of allowed models in a Python file (#6251) 2022-12-01 14:43:36 -05:00
Michelle Ark
2289e45571 Exposures support metrics (#6342)
* exposures support metrics
2022-12-01 11:01:16 -05:00
dependabot[bot]
b5d303f12a Bump mashumaro[msgpack] from 3.0.4 to 3.1 in /core (#6108)
* Bump mashumaro[msgpack] from 3.0.4 to 3.1.1 in /core

Bumps [mashumaro[msgpack]](https://github.com/Fatal1ty/mashumaro) from 3.0.4 to 3.1.
- [Release notes](https://github.com/Fatal1ty/mashumaro/releases)
- [Commits](https://github.com/Fatal1ty/mashumaro/compare/v3.0.4...v3.1)

---
updated-dependencies:
- dependency-name: mashumaro[msgpack]
  dependency-type: direct:production
  update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: Michelle Ark <michelle.ark@dbtlabs.com>
2022-11-30 17:32:47 -05:00
Mila Page
c3be975783 Ct 288/convert 070 incremental test (#6330)
* Convert incremental schema tests.

* Drop the old test.

* Bad git add. My disappoint is immeasurable and my day has been ruined.

* Adjustments for flake8.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-11-29 12:47:20 -08:00
Mila Page
47c2edb42a Ct 1518/convert 063 relation names tests (#6304)
* Convert old test.

Add documentation. Adapt and reenable previously skipped test.

* Convert test and adapt and comment for current standards.

* Remove old versions of tests.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-11-29 12:25:36 -08:00
Stu Kilgore
b3440417ad Add GHA workflow to build CLI API docs (#6187) 2022-11-29 13:30:47 -06:00
leahwicz
020f639c7a Update stale.yml (#6258) 2022-11-29 09:40:59 -05:00
Mila Page
55db15aba8 Convert test 067. (#6305)
* Convert test 067. One bug outstanding.

* Test now working! Schema needed renaming to avoid 63 char max problems

* Remove old test.

* Add some docs and rewrite.

* Add exception for when audit tables' schema runs over the db limit.

* Code cleanup.

* Revert exception.

* Round out comments.

* Rename what shouldn't be a base class.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-11-29 00:06:07 -08:00
Itamar Hartstein
bce0e7c096 BaseContext: expose md5 function in context (#6247)
* BaseContext: expose md5 function in context

* BaseContext: add return value type

* Add changie entry

* rename "md5" to "local_md5"

* fix test_context.py
2022-11-28 10:23:40 -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
Gerda Shank
7d7066466d CT 1537 fix event test and rename a couple of fields (#6293)
* Rename MacroEvent to JinjaLog

* Rename ConnectionClosed/2

* Fix LogSeedResult

* Rename ConnectionLeftOpen events, fix test_events.py

* Update events README.md, add "category" to EventInfo

* Rename GeneralMacroWarning to JinjaLogWarning
2022-11-22 14:54:20 -05:00
Emily Rockman
517576c088 add back in conditional node length check (#6298) 2022-11-21 21:20:55 -08:00
leahwicz
987764858b Revert "Bump python from 3.10.7-slim-bullseye to 3.11.0-slim-bullseye in /docker (#6180)" (#6281)
This reverts commit 8e28f5906e.
2022-11-17 09:14:22 -05:00
FishtownBuildBot
a235abd176 Add new index.html and changelog yaml files from dbt-docs (#6265) 2022-11-16 17:00:33 +01:00
dependabot[bot]
9297e4d55c Update pathspec requirement from ~=0.9.0 to >=0.9,<0.11 in /core (#5917)
* Update pathspec requirement from ~=0.9.0 to >=0.9,<0.11 in /core

Updates the requirements on [pathspec](https://github.com/cpburnz/python-pathspec) to permit the latest version.
- [Release notes](https://github.com/cpburnz/python-pathspec/releases)
- [Changelog](https://github.com/cpburnz/python-pathspec/blob/master/CHANGES.rst)
- [Commits](https://github.com/cpburnz/python-pathspec/compare/v0.9.0...v0.10.1)

---
updated-dependencies:
- dependency-name: pathspec
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-11-15 22:02:37 -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
Michelle Ark
eae98677b9 s/gitlab/github for flake8 precommit repo (#6252) 2022-11-15 10:30:00 -05:00
Matthew McKnight
66ac107409 [CT-1262] Convert dbt_debug (#6125)
* init pr for dbt_debug test conversion

* removal of old test

* minor test format change

* add new Base class and Test classes

* reformatting test, new method for capsys and error messgae to check, todo fix badproject

* refomatting tests, ready for review

* checking yaml file, and small reformat

* modifying since update wasn't working in ci/cd
2022-11-14 14:22:48 -06:00
Michelle Ark
39c5c42215 converting 044_test_run_operations (#6122)
* converting 044_test_run_operations
2022-11-14 10:39:57 -05:00
dependabot[bot]
9f280a8469 Update colorama requirement from <0.4.6,>=0.3.9 to >=0.3.9,<0.4.7 in /core (#6144)
* Update colorama requirement in /core

Updates the requirements on [colorama](https://github.com/tartley/colorama) to permit the latest version.
- [Release notes](https://github.com/tartley/colorama/releases)
- [Changelog](https://github.com/tartley/colorama/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tartley/colorama/compare/0.3.9...0.4.6)

---
updated-dependencies:
- dependency-name: colorama
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-11-13 09:57:33 -05:00
Joe Berni
73116fb816 feature/favor-state-node (#5859) 2022-11-09 10:58:01 -06:00
Stu Kilgore
f02243506d Convert postgres index tests (#6228) 2022-11-08 15:30:29 -06:00
Stu Kilgore
d5e9ce1797 Convert color tests to pytest (#6230) 2022-11-08 15:25:57 -06:00
Stu Kilgore
4e786184d2 Convert threading tests to pytest (#6226) 2022-11-08 08:56:10 -06:00
Chenyu Li
930bd3541e properly track hook running (#6059) 2022-11-07 10:44:29 -06:00
Gerda Shank
6c76137da4 CT 1443 remove root path (#6172)
* Remove root_path

* Bump manifest schema to 8

* Update tests and compability utility for v8, root_path removal
2022-11-04 16:38:26 -04:00
Gerda Shank
68d06d8a9c Combine various print result log events with different levels (#6174)
* Combine various print result log events with different levels

* Changie

* more merge cleanup

* Specify DynamicLevel for event classes that must specify level
2022-11-04 14:26:37 -04:00
Rachel
d0543c9242 Updates lib to use new profile name functionality (#6202)
* Updates lib to use new profile name functionality

* Adds changie entry

* Fixes formatting
2022-11-04 10:05:24 -07:00
Michelle Ark
cfad27f963 add typing to DepsTask.run (#6192) 2022-11-03 17:35:16 -04:00
Emily Rockman
c3ccbe3357 add python version and upgrade action (#6204) 2022-11-03 09:13:00 -05:00
dependabot[bot]
8e28f5906e Bump python from 3.10.7-slim-bullseye to 3.11.0-slim-bullseye in /docker (#6180)
* Bump python from 3.10.7-slim-bullseye to 3.11.0-slim-bullseye in /docker

Bumps python from 3.10.7-slim-bullseye to 3.11.0-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-11-02 08:40:51 -07:00
FishtownBuildBot
d23285b4ba Add new index.html and changelog yaml files from dbt-docs (#6112) 2022-11-02 08:36:56 -07:00
Michelle Ark
a42748433d converting 023_exit_codes_tests (#6105)
* converting 023_exit_codes_tests

* use packages fixture, clean up test names
2022-11-01 16:26:12 -04:00
Emily Rockman
be4a91a0fe Convert messages to struct logs (#6064)
* Initial structured logging changes

* remove "this" from core/dbt/events/functions.py

* CT-1047: Fix execution_time definitions to use float

* CT-1047: Revert unintended checking of changes to functions.py

* WIP

* first pass to resolve circular deps

* more circular dep resolution

* remove a bunch of duplication

* move message into log line

* update comments

* fix field that wen missing during rebase

* remove double import

* remove some comments and extra code

* fix pre-commit

* rework deprecations

* WIP converting messages

* WIP converting messages

* remove stray comment

* WIP more message conversion

* WIP more message conversion

* tweak the messages

* convert last message

* rename

* remove warn_or_raise as never used

* add fake calls to all new events

* fix some tests

* put back deprecation

* restore deprecation fully

* fix unit test

* fix log levels

* remove some skipped ids

* fix macro log function

* fix how messages are built to match expected outcome

* fix expected test message

* small fixes from reviews

* fix conflict resolution in UI

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
Co-authored-by: Peter Allen Webb <peter.webb@dbtlabs.com>
2022-10-31 12:04:56 -05:00
Emily Rockman
8145eed603 revert to community action (#6163) 2022-10-27 16:10:58 -05:00
Emily Rockman
fc00239f36 point to correct workflow (#6161)
* point to correct workflow

* add inputs
2022-10-27 14:05:09 -05:00
Ian Knox
77dfec7214 more ergonomic profile name handling (#6157) 2022-10-27 10:49:27 -05:00
Emily Rockman
7b73264ec8 switch out to use internal action for triage labels (#6120)
* switch out to use our action

* point to main
2022-10-27 08:33:15 -05:00
Mila Page
1916784287 Ct 1167/030 statement tests conversion (#6109)
* Convert test to functional set.

* Remove old statement tests from integration test set.

* Nix whitespace

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-10-26 03:37:44 -07: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
Ian Knox
c2856017a1 [BUGFIX] Force tox to update pip (fixes psycopg2-binary @ 2.9.5) (#6134) 2022-10-25 13:01:38 -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
Michelle Ark
17b82661d2 convert 027 cycle test (#6094)
* convert 027 cycle test

* remove no-op expect_pass=False

* remove postgres from test names
2022-10-21 11:41:51 -04:00
Michelle Ark
6c8609499a Add 'michelleark' to changie's core_team list (#6084) 2022-10-20 14:41:41 -04:00
Peter Webb
53ae325576 CT-1099: Migrate test 071_commented_yaml_regression_3568_tests (#6106) 2022-10-20 12:43:30 -04:00
Mila Page
a7670a3ab9 Add unit tests for recent stringifier functors added to events library. (#6095)
Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-10-19 22:52:32 -07:00
Mila Page
ff2f1f42c3 Working solution serialization bug. (#5874)
* Create functors to initialize event types with str-type member attributes. Before this change, the spec of various classes expected base_msg and msg params to be str's. This assumption did not always hold true. post_init hooks ensures the spec is obeyed.
* Add new changelog.
* Add msg type change functor to a few other events that could use it.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-10-18 12:20:30 -07:00
Luke Bassett
35f7975d8f Updated string formatting on non-f-strings. (#6086)
* Updated string formatting on non-f-strings.

Found all cases of strings separated by white space on a single line and
removed white space separation. EX: "hello " "world" -> "hello world".

* add changelog entry
2022-10-17 15:58:31 -05:00
Eve Johns
a9c8bc0e0a f-string cleanup #6068 (#6082)
* fix f string issue

* removed one space

* Add changelog

* fixed return format

Co-authored-by: Leah Antkiewicz <leah.antkiewicz@fishtownanalytics.com>
2022-10-17 16:58:04 -04:00
Peter Webb
73aebd8159 CT-625: Fail with clear message for invalid materialized vals (#6025)
* CT-625: Fail with clear message for invalid materialized vals

* CT-625: Increase test coverage, run pre-commit checks

* CT-625: run black on problem file

* CT-625: Add changelog entry

* CT-625: Remove test that didn't make sense
2022-10-14 16:14:32 -04:00
Gerda Shank
9b84b6e2e8 Initial structured logging changes (#5954)
Co-authored-by: Peter Allen Webb <peter.webb@dbtlabs.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-10-14 13:57:46 -04:00
colin-rogers-dbt
095997913e migrate 034 integration test to functional (#6054)
* migrate 034 integration test to functional

* formatting fixes

* move to adapter directory

* add extra args
2022-10-12 15:24:51 -07:00
pgoslatara
6de1d29cf9 Allowing partitions in external table to be a list (#5930)
* Allowing partitions in external table to be a list

* Adding changelog entry
2022-10-12 15:23:58 -07:00
Mila Page
87db12d05b Ct 1049/migrate 016 macro tests (#5780)
* Migrate test

* Remove old integration test.

* Simplify object definitions since we enforce python 3

* Factor many fixtures into a file.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-10-12 13:37:08 -07:00
Stu Kilgore
dcc70f314f Generate API docs (#6022) 2022-10-12 08:56:24 -05:00
Matteo Ferrando
dcd6ef733b fix: check length of args of python model function before accessing it (#6042)
* fix: check length of args of python model function before accessing it

* Add test

* changie
2022-10-11 14:34:27 -07:00
Emily Rockman
85e415f50f Validate enabled config is a bool for sources, exposures and metrics (#6038)
* clean up tests, validate enabled config is a bool

* clean up code, add model test

* add changelog

* move validation into proper validation methods

* fix source defn validation

* add optional tables logic

* use existing validation
2022-10-11 16:10:50 -05:00
Matthew McKnight
2c684247e9 [CT-1271] Test Query Comment conversion (#5971)
* init query_comment test conversion pr

* importing model and macro, changing to new project_config_update, tests passing locally for core

* delete old integration test

* trying to test against other adapters

* update to main

* file rename

* file rename

* import change

* move query_comment directory to functional/

* move test directory back to adapter zone

* update to main

* updating core test based on feedback from @gshank

* testing removing target checking
2022-10-11 14:58:32 -05:00
Maximilian Roos
3d09531cda Make mypy pass from the command line (#5983)
* Make `mypy` pass from the command line
2022-10-11 13:10:15 -05:00
leahwicz
fc1227e0b1 Adding 1.3.latest branch to testing matrix (#6045) 2022-10-11 10:44:16 -04:00
Maximilian Roos
dc96352493 Add dmypy cache to gitignore (#5978)
* Add dmypy cache to gitignore
2022-10-10 09:14:55 -05:00
Jared Rimmer
725cf81af6 Add friendlier error messages when packages yml is malformed (#5812)
* Add friendlier error messages when packages yml is malformed

* Add Changelog

* Add validate classmethod to PackageConfig with tests

* Fix failing tests
2022-10-10 08:44:31 -05:00
Emily Rockman
558468e854 Consolidate exception (#6024)
* combine repeated exception logic

* fix params

* changelog
2022-10-07 13:07:18 -05:00
dependabot[bot]
95ad1ca4f8 Bump black from 22.8.0 to 22.10.0 (#6019)
* Bump black from 22.8.0 to 22.10.0

Bumps [black](https://github.com/psf/black) from 22.8.0 to 22.10.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/22.8.0...22.10.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-10-07 08:59:19 -05:00
Maximilian Roos
02a69c8f4f Put black config in explicit config (#5947) 2022-10-06 11:47:04 -05:00
dave-connors-3
7dbdfc88e0 add -f for seeds (#5991)
* add -f for seeds

* ole changie

* more specific changlog description

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-10-05 16:13:21 -05:00
Andy
2002791ec1 Andy/fix init comment (#5684)
* edited comment to correctly specify that views are set, not tables

* updated init test to match starter project change

* added changelog

* update 3 other occurrences of the init test for text update
2022-10-05 15:46:27 -05:00
Emily Rockman
29d96bd6bf Convert 019_analysis_tests (#6006)
* convert 019 test

* add duplicate analysis test
2022-10-05 13:41:49 -05:00
Peter Webb
d01245133a CT-1150: Include flat_graph in manifest.deepcopy(), tests (#5975)
* CT-1150: Include flat_graph in manifest.deepcopy(), tests

* append to changelog
2022-10-05 13:56:29 -04:00
Emily Rockman
23c8ac230c convert 025 to new framework, add metrics dupe test (#6004) 2022-10-05 08:42:07 -05:00
Gerda Shank
43d9ee3470 Remove 015_cli_invocation_tests directory (#5961) 2022-10-03 13:31:45 -04:00
colin-rogers-dbt
50fe25d230 consolidate timestamp logic (#5979)
* Consolidate date macros into dates.sql

* rename to timestamps.sql

* fix whitespace + add changie

* cleanup macros and add testing

* fix whitespace

* remove now macro

* fix functional test

* remove local config

* make snowflake backwards compat return utc

* move timestamps to adaptor base tests

* move backcompat macros to respective adapters

* change timestamp param to source_timestamp

* move timestamps.py to utils

* update changie.yaml

* make expected schema a fixture

* formatting

* add debug message to assert

* fix changie.yaml

* Update tests/adapter/dbt/tests/adapter/utils/test_timestamps.py

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

* Update plugins/postgres/dbt/include/postgres/macros/timestamps.sql

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

* Update .changie.yaml

* add backcompat utc

* remove current_timestamp_in_utc

* remove convert_timezone

* add _in_utc_backcompat

* fix macro_calls typo

* add expected sql validation to test_timestamps

* make expected_sql optional

* improve sql check string comparison test

* remove extraneous test file

* add timestamp casting back

* Update plugins/postgres/dbt/include/postgres/macros/adapters.sql

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

* add check_relation_has_expected_schema to comments

* fix whitespace

* remove default impl of current_timestamp

* manual changie log fix

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2022-09-30 16:37:24 -07:00
colin-rogers-dbt
a79960fa64 Consolidate date macros into timestamps.sql (#5838)
* Consolidate date macros into dates.sql

* rename to timestamps.sql

* fix whitespace + add changie

* cleanup macros and add testing

* fix whitespace

* remove now macro

* fix functional test

* remove local config

* make snowflake backwards compat return utc

* move timestamps to adaptor base tests

* move backcompat macros to respective adapters

* change timestamp param to source_timestamp

* move timestamps.py to utils

* update changie.yaml

* make expected schema a fixture

* formatting

* add debug message to assert

* fix changie.yaml

* Update tests/adapter/dbt/tests/adapter/utils/test_timestamps.py

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

* Update plugins/postgres/dbt/include/postgres/macros/timestamps.sql

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

* Update .changie.yaml

* add backcompat utc

* remove current_timestamp_in_utc

* remove convert_timezone

* add _in_utc_backcompat

* fix macro_calls typo

* add expected sql validation to test_timestamps

* make expected_sql optional

* improve sql check string comparison test

* remove extraneous test file

* add timestamp casting back

* Update plugins/postgres/dbt/include/postgres/macros/adapters.sql

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

* add check_relation_has_expected_schema to comments

* fix whitespace

* remove default impl of current_timestamp

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2022-09-30 15:33:12 -07:00
Emily Rockman
fa4f9d3d97 Disabled Models in schema files (#5868)
* clean up debugging

* reword some comments

* changelog

* add more tests

* move around the manifest.node

* fix typos

* all tests passing

* move logic for moving around nodes

* add tests

* more cleanup

* fix failing pp test

* remove comments

* add more tests, patch all disabled nodes

* fix test for windows

* fix node processing to not overwrite enabled nodes

* add checking disabled in pp, fix error msg

* stop deepcopying all nodes when processing

* update error message
2022-09-29 15:24:08 -05:00
Emily Rockman
73385720b4 Update 0.0.0.md (#5973) 2022-09-29 09:57:22 -05:00
github-actions[bot]
c2ab2971b0 Bumping version to 1.4.0a1 and generate changelog (#5965)
* Bumping version to 1.4.0a1 and generate CHANGELOG

* Updating Changelog files

* Removed Changelog entry for alpha

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: Leah Antkiewicz <leah.antkiewicz@fishtownanalytics.com>
2022-09-29 09:14:39 -04:00
leahwicz
0e60fc1078 Update Version Bump to include Homebrew in PATH (#5963) 2022-09-28 14:18:29 -04:00
Matthew McKnight
4f2fef1ece [CT-1166] test_aliases conversion (#5884)
* init pr for 026 test conversion

* removing old test, got all tests setup, need to find best way to handle regex in new test and see what we would actually want to do to test check we didn't run anything against

* changes to test_alias_dupe_thorews_exeption passing locally now

* adding test cases for final test

* following the create new shcema method tests are passing up for review for core code

* noving alias test to adapter zone

* adding Base Classes

* changing ref to fixtures

* add double check to test

* minor change to alt schema name formation, removal of unneeded setup fixture

* typo in model names

* update to main

* pull models/schemas/macros into a fixtures file
2022-09-28 11:03:12 -05:00
Gerda Shank
3562637984 Remove parsers/source.py type ignores (#5953) 2022-09-28 11:24:59 -04:00
Callum McCann
17aca39e1c Adding metric expression validation (#5873)
* adding validation

* changie

* code formatting

* updating for review

* updating tests
2022-09-27 12:38:03 -04:00
Yoshiaki Ishihara
59744f18bb Fix typos of comments in core/dbt/adapters/ (#5693) 2022-09-27 09:10:24 -07:00
Rachel
f1326f526c Runtime: Prevent introspective queries at compile (SL only) (#5926)
* Preliminary changes to keep compile from connecting to the warehouse for runtime calls

* Adds option to lib to skip connecting to warehouse for compile; adds prelim tests

* Removes unused imports

* Simplifies test and renames to SqlCompileRunnerNoIntrospection

* Updates name in tests

* Spacing

* Updates test to check for adapter connection call instead of compile and execute

* Removes commented line

* Fixes test names

* Updates plugin to postgres type as snowflake isn't available

* Fixes docstring

* Fixes formatting

* Moves conditional logic out of class

* Fixes formatting

* Removes commented line

* Moves import

* Unmoves import

* Updates changelog

* Adds further info to method docstring
2022-09-27 09:49:55 -04:00
Jeremy Cohen
834ac716fd Prefer internal macros when called explicitly (#5907)
* Add functional test

* Prefer internal macros when called explicitly

* Add changelog entry

* update tests format

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-09-27 08:50:55 -04:00
Doug Beatty
0487b96098 Array macros (#5823)
* Helper macro to cast from array to string

* Default implementations and tests for array macros

* Trim Trailing Whitespace

* Changelog entry

* Remove dependence upon `cast_array_to_string` macro

* pre-commit fixes

* Remove `cast_array_to_string` macro

* pre-commit fix

* Trivial direct test; array_concat/append test non-triviallly indirectly

* Remove vestigial `lstrip`
2022-09-26 13:40:15 -06:00
FishtownBuildBot
dbd36f06e4 Add new index.html and changelog yaml files from dbt-docs (#5925) 2022-09-26 14:00:04 -05:00
dave-connors-3
38ada8a68e merge exclude columns for incremental models (#5457)
* exlcude cols like in dbt_utils.star

* dispatch macro

* changelog entry

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2022-09-26 14:49:12 -04:00
Doug Beatty
e58edaab2d Test for Koalas DataFrames (#5928) 2022-09-26 12:41:56 -06:00
Doug Beatty
c202e005cd Tests for current_timestamp (#5935)
* Tests for `current_timestamp`

* Black formatting
2022-09-26 12:31:36 -06:00
Peter Webb
8129862b3c CT-1221 add handle to changie (#5923)
* Add 'peterallenwebb' to changie's core_team list.

* fix accidental line break
2022-09-26 11:44:20 -04:00
Drew Banin
4e8aa007cf Fix adapter reset race condition in lib.py (#5921)
* (#5919) Fix adapter reset race condition in lib.py

* run black

* changie
2022-09-26 10:26:20 -04:00
Doug Beatty
fe88bfabbf Click CLI profiles directory (#5896)
* Default directories for projects and profiles

* Re-write of get_nearest_project_dir()

* Trim Trailing Whitespace

* Functionally equivalent resolvers
2022-09-24 10:47:47 -06:00
Gerda Shank
5328a64df2 CT 815 partial parsing handling of deleted metrics (#5920)
* Update delete_schema_metric to schedule referencing nodes for reparsing

* Changie
2022-09-23 18:48:00 -04:00
Chenyu Li
87c9974be1 improve error message for parsing args (#5895)
* improve error message for parsing args

* update error message

* Update models.py

* skip stack_trace for all dbt Exceptions
2022-09-23 13:31:10 -07:00
Emily Rockman
f3f509da92 update disabled metrics/exposures to use add_disabled (#5909)
* update disabled metrics/exposures to use add_disabled

* put back func fo tests

* add pp logic

* switch elif

* fix test name

* return node
2022-09-23 13:24:37 -05:00
dave-connors-3
5e8dcec2c5 update flag to -f (#5908) 2022-09-23 20:20:29 +02:00
Chenyu Li
56783446db PySpark dataframe related tests (#5906)
Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2022-09-22 16:27:27 -07:00
Chenyu Li
207cc0383d initial support for a .dbtignore (#5897) 2022-09-22 09:06:35 -07:00
leahwicz
49ecd6a6a4 Adding missing permissions on GHA (#5870)
* Adding missing permissions on GHA

* Adding read all permissions explicitly
2022-09-21 14:53:27 -04:00
dave-connors-3
c109f39d82 add optional shorthand to full refresh command (#5879)
* add optional shorthand to full refresh command

* changie

* replace full refresh with shorthand in functional test
2022-09-21 14:37:28 -04:00
Ian Knox
fd778dceb5 Profiling and Adapter management work with Click (#5892) 2022-09-21 11:23:26 -05:00
Emily Rockman
e402241e0e Validate exposure names and add label (#5844)
* first pass

* add label and name validation

* changelog

* fix tests

* convert ParsingError to Deprecation

* fix bug where label did not end up in parsed node

* update deprecation msg
2022-09-21 10:24:44 -05:00
Emily Rockman
a6c37c948d Add name validation for metrics (#5841)
* add tests, add name validation

* tweak test

* small update

* change to 250 char limit, tweak message
2022-09-21 09:31:13 -05:00
Daniel Messias
fd886cb7dd ConfigSelectorMethod should check for bools (#5889)
* ConfigSelectorMethod should check for bools

* Add changelog entry

* Add support for lists and test cases

* Typo and formatting in test

* pre-commit linting
2022-09-21 10:20:14 -04:00
James McNeill
b089a471b7 implement type_boolean macro (#5875)
* implement type_boolean macro

* changie result
2022-09-20 19:24:25 -06:00
Emily Rockman
ae294b643b Manifest deserialization error with disabled models (#5891)
* account for disabled nodes in renaming attributes

* tweak naming
2022-09-20 14:27:25 -05:00
colin-rogers-dbt
0bd6df0d1b [CT-1101] 024_custom_schema_tests (#5828)
* create functional custom schema tests

* delete old integration tests

* changie log

* formatting fixes

* delete changie entry and errant comment
2022-09-20 10:42:07 -07:00
Gerda Shank
7b1d61c956 Ct 1191 event history cleanup (#5858)
* Change Exceptions in events to strings. Refactor event_buffer_handling.

* Changie

* fix fire_event call MainEncounteredError

* Set EventBufferFull message when event buffer >= 10,000
2022-09-20 12:44:33 -04:00
Chenyu Li
646a0c704f restrict python submission (#5822)
Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2022-09-20 09:39:20 -07:00
Doug Beatty
bbf4fc30a5 Default to current working directory for profiles.yml and fall back to ~/.dbt (#5717)
* Method for capturing standard out during testing (rather than logs)

* Allow dbt exit code assertion to be optional

* Verify priority order to search for profiles.yml configuration

* Updates after pre-commit checks

* Test searching for profiles.yml within the dbt project directory before `~/.dbt/`

* Refactor `dbt debug` to move to the project directory prior to looking up profiles directory

* Search the current working directory for profiles.yml

* Changelog

* Formatting with Black

* Move `run_dbt_and_capture_stdout` into the test case

* Update CLI help text

* Unify separate DEFAULT_PROFILES_DIR definitions

* Remove unused PROFILE_DIR_MESSAGE

* Remove unused DEFAULT_PROFILES_DIR

* Use shared definition of DEFAULT_PROFILES_DIR

* Define global vs. local profiles location and dynamically determine the default

* Restore original

* Remove function for determining the default profiles directory
2022-09-20 08:44:15 -04:00
jared-rimmer
6baaa2bcb0 Add metadata env method to provider context (#5794)
* Add dbt_metadata_envs contextproperty to ProviderContext

* Refactor helper methods into functions

* Fix code quality failures

* Add Changelog
2022-09-20 08:41:44 -04:00
Chenyu Li
13a595722a add support for custom file ending (#5845) 2022-09-19 13:58:38 -07:00
Sam Debruyn
3680b6ad0e remove source quoting setting in adapter tests (#5839)
* remove source quoting setting in adapter tests

* changelog entry

* formatting
2022-09-19 11:00:12 -07:00
Ian Knox
4c29d48d1c Flags work with Click (#5790) 2022-09-19 12:36:38 -05:00
Chenyu Li
e00eb9aa3a fix multiple dbt.config.get in python model (#5850)
* fix multiple dbt.config.get in python model

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>
2022-09-16 15:07:59 -07:00
Jeremy Cohen
f5a94fc774 Back/fwd compatibility for renamed metrics attributes (#5825)
* Naive handling for metric attr renames

* Add tests for bwd/fwd compatibility

* Add deprecation

* Add changelog entry

* PR feedback

* Small fixups

* emmyoop's suggestions

Co-authored-by: Callum McCann <cmccann51@gmail.com>
2022-09-16 11:21:35 +02:00
Sam Debruyn
b98af4ce17 remove key as reserved keyword from test_bool_or (#5818) 2022-09-15 09:44:25 -05:00
Matthew McKnight
b0f8d3d2f1 [CT-1100] 021_test_concurrency test conversion (#5753)
* init push for 021_test_concurrency conversion

* ref to self, delete old integration tests, core passing locally

* creating base class to send setup to snowflake

* making changes to store all setup in core, todo: remove util changes after 1050 is merged

* swap sql seeds to csv

* white space removal

* rewriting seed to see if it fixes issue in snowflake

* attempt to rewrite file for test in snowflake

* update to main

* remove unneeded variable to seeds

* remove unneeded snowflake specific code
2022-09-14 15:49:36 -05:00
Emily Rockman
6c4577f44e Add config to disable metrics/exposures (#5815)
* first pass adding disabled functionality to metrics and exposures

* first pass at getting metrics disabled

* add unsaved file

* fix up comments

* Delete tmp.csv

* fix test

* add exposure logic, fix merge from main

* change when nodes are added to manifest, finish tests

* add changelog

* removed unused code

* minor cleanup
2022-09-14 14:35:38 -05:00
Matthew McKnight
89ee5962f5 [CT-1050] convert 020_ephemeral_test (#5699)
* init file creation for test_ephemeral conversion

* creating base class to run seed through and pass along to classes to test against

* laid out basic flow of tests, need to finish by figuring out how to handle the assertTrue sections and fix error thats occuring

* added creation and comparison of sql and expected result, seeing issue with extra appended test_ on some and issue with errorhandling regarding expect pass

* working on fixing view structure

* update to expected_sql file

* update to expected_sql file

* directory rename, close on all tests need to fix the test_test_ name change for first two tests and figure out why the new test is calling error instead of skipped in status

* renamed expected_sql to include the test_test_ephemeral style name, organized how models are imported into test classes

* move ephemeral functional test to adapter zone

* trying to include the BaseEphemeralMulti class to send to snowflake

* trying to fix snowflake test

* trying to fix snowflake test

* creation of second Base class to feed into others for testing purposes

* found way to check type of warehouse to make data type change for snowflake

* move seed into fixture, to be able to import it from core for adapter tests

* convert to csv and get test passing in core

* remove snowflake specific stuff from util

* remove whitespace

* update to main
2022-09-14 12:00:02 -05:00
Ian Knox
a096202b28 Complete CLI modeling for Click (#5789) 2022-09-14 10:27:47 -05:00
Stu Kilgore
7da7c2d692 Convert default selectors tests to pytest (#5820) 2022-09-13 11:47:13 -05:00
dependabot[bot]
1db48b3cca Bump python from 3.10.6-slim-bullseye to 3.10.7-slim-bullseye in /docker (#5805)
* Bump python from 3.10.6-slim-bullseye to 3.10.7-slim-bullseye in /docker

Bumps python from 3.10.6-slim-bullseye to 3.10.7-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-09-12 10:58:24 -07:00
Chenyu Li
567847a5b0 add a base python job helper class (#5802)
* add a base python job helper class

* fix comment, add changelog

* fix quote for adapters
2022-09-12 10:44:19 -07:00
Sam Debruyn
9894c04d38 fix dead anchor link in PR template (#5814)
* fix dead anchor link in PR template

The link did not go to the anchor directly, now it does

* changelog entry
2022-09-12 11:08:30 -04:00
Callum McCann
b26280d1cf Altering Window Metric Attribute To Match Freshness Tests (#5793)
* changing window spec

* more updates

* adding to v7 json?

* chenyu rules

* updating for formatting

* updating metric deferral test
2022-09-09 16:33:32 -07:00
Callum McCann
cfece2cf51 Renaming Attributes In Metric Spec (#5775)
* making updates - see what fails

* updating tests

* adding timestamp to ok_metric_no_model

* adding changie and fixing description error

* test fixes

* updating schema renderer

* fixing test_yaml_render

* file cleaning and window tests
2022-09-09 14:59:52 -04:00
Stu Kilgore
79da002c3c Fix warnings as errors during tests (#5800)
Added RunResultWarningMessage event to support this change.
2022-09-09 12:50:15 -05:00
Bertjan Broeksema
e3f827513f Remove tmp file after test passed (#5749)
* Remove tmp file after test passed

* Add changelog entry
2022-09-09 11:14:43 -04:00
Gerda Shank
10b2a7e7ff Convert test/integration/074_postgres_unlogged_table_tests (#5752)
* Convert test/integration//074_postgres_unlogged_table_tests

* Remove old test
2022-09-08 16:54:03 -04:00
jared-rimmer
82c8d6a7a8 Add invocation_args_dict to ProviderContext (#5782)
* Add invocation_args_to_dict to ProviderContext

* Change invocation_args_to_dict contextproperty to invocation_args_dict

* Fix invocation_args_dict builtin test

* Add CHANGELOG entry

* Fix formatting
2022-09-08 15:31:40 -04:00
Gerda Shank
c994717cbc Call build_flat_graph in merge_from_artifact (#5786) 2022-09-08 15:30:26 -04:00
Callum McCann
e3452b9a8f Add Window Attribute for Metrics (#5722)
* file changes

* changing to window

* adding test

* adding changie for feature

* fixing commits

* fixing tests

* adding timestamp

* fixing graph unparsed

* changing default value
2022-09-07 10:45:08 -04:00
Aram Panasenco
e95e36d63b Include py.typed in MANIFEST.in (#5703)
This enables packages that install dbt-core from pypi to use mypy.
2022-09-06 22:03:12 -04:00
jared-rimmer
74f7416144 Add extra rm command in make clean to remove all .coverage files (#5759)
* Add extra rm command in make clean to remove all .coverage files

* Add Changie entry
2022-09-06 21:36:35 -04:00
Mila Page
1feeb804f4 Update makefile to match our CI (#5763)
* Add structured logging test and provide CI env vars to integration conditionally.
* Add the crazy inline if make feature and ax unneeded variable

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-09-06 15:42:50 -07:00
Mila Page
0f6e4f0e32 Ct 866/migrate hook tests fixed (#5760)
* Finish converting first test file.
* Finish test conversion.
* Remove old integration hook tests.
* Move location of schema.yml to models directory.
* fix snapshot delete test that was failing
* Add the extra env var check for our CI.
* Add changelog
* Remove naive json flag check and instead force all integration tests to check for environment variables using flag routine.
* Revise the changelog to be more of an explanation.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-09-06 12:22:29 -07:00
Emily Rockman
2b44c2b456 Convert experimental parser tests (#5772)
* WIP

* fixed up tests

* remove old test
2022-09-06 14:11:22 -05:00
leahwicz
2bb31ade39 Update release-branch-tests.yml (#5767) 2022-09-06 14:46:53 -04:00
Mila Page
0ce12405c0 Move docs in from Jinja. (#5762)
Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-09-06 10:05:05 -07:00
dependabot[bot]
b8c13e05db Bump black from 22.6.0 to 22.8.0 (#5750)
* Bump black from 22.6.0 to 22.8.0

Bumps [black](https://github.com/psf/black) from 22.6.0 to 22.8.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/22.6.0...22.8.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

* Remove newline

* Delete Dependency-20220901-154946.yaml

* Add automated changelog yaml from template for bot PR

* Delete Dependency-20220906-132643.yaml

* Add automated changelog yaml from template for bot PR

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-09-06 11:31:13 -05:00
Emily Rockman
64268d2f9b Fix label selection syntax and trigger (#5754)
* Fix label selection syntax and trigger

* update version
2022-09-06 08:21:21 -05:00
Jeremy Cohen
8c8be68701 Roadmap update (Aug 2022) (#5748)
* Add dbt Core roadmap as of August 2022

* Cody intro

* Florian intro

* Lint my markdown

* add blurb on 1.5+ for Python next steps

* Revert "add blurb on 1.5+ for Python next steps"

This reverts commit 1659a5a727.

* PR feedback, self review

Co-authored-by: Cody Peterson <cody.dkdc2@gmail.com>
Co-authored-by: Florian Eiden <florian.eiden@dbtlabs.com>
2022-09-01 00:31:51 +02:00
Doug Beatty
1df713fee9 Test priority order of profiles directory configuration (#5715)
* Method for capturing standard out during testing (rather than logs)

* Allow dbt exit code assertion to be optional

* Verify priority order to search for profiles.yml configuration

* Updates after pre-commit checks

* Move `run_dbt_and_capture_stdout` into the test case
2022-08-30 17:18:17 -06:00
Gerda Shank
758afd4071 ADR for why we're using betterproto for protobuf (#5726) 2022-08-30 12:58:44 -04:00
Jeremy Cohen
0f9200d356 Update team ownership (#5694) 2022-08-30 15:24:34 +02:00
github-actions[bot]
5f59ff1254 Bumping version to 1.3.0b2 and generate changelog (#5724)
* Bumping version to 1.3.0b2 and generate CHANGELOG

* Remove newlines

* Remove newline

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-08-29 11:11:35 -04:00
dependabot[bot]
49e7bdbef9 Bump mashumaro[msgpack] from 3.0.3 to 3.0.4 in /core (#5649)
* Bump mashumaro[msgpack] from 3.0.3 to 3.0.4 in /core

Bumps [mashumaro[msgpack]](https://github.com/Fatal1ty/mashumaro) from 3.0.3 to 3.0.4.
- [Release notes](https://github.com/Fatal1ty/mashumaro/releases)
- [Commits](https://github.com/Fatal1ty/mashumaro/compare/v3.0.3...v3.0.4)

---
updated-dependencies:
- dependency-name: mashumaro[msgpack]
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

* Remove newline

* Remove newline

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-08-25 09:00:46 -04:00
Stu Kilgore
5466fa5575 Add supported languages to materializations (#5695)
* Add supported languages to materializations

* Add changie entry

* Linting

* add more error and only get supported language for materialization macro, update schema

* fix test and add more check

Co-authored-by: Chenyu Li <chenyu.li@dbtlabs.com>
2022-08-24 12:08:16 -07:00
dependabot[bot]
f8f21ee707 Bump python from 3.10.5-slim-bullseye to 3.10.6-slim-bullseye in /docker (#5623)
* Bump python from 3.10.5-slim-bullseye to 3.10.6-slim-bullseye in /docker

Bumps python from 3.10.5-slim-bullseye to 3.10.6-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template for bot PR

* Update Dependency-20220808-132327.yaml

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: Chenyu Li <chenyu.li@dbtlabs.com>
2022-08-24 11:20:00 -07:00
Chenyu Li
436737dde5 more complex visit_Call to parse chained command (#5677)
* more complex visit_Call

* add changelog

* traversing all of the tree
2022-08-24 08:02:19 -07:00
Jeremy Cohen
7f8d9a7af9 Check dbt-core version requirements when installing Hub packages (#5651)
* First cut at checking version compat for hub pkgs

* Account for field rename

* Add changelog entry

* Update error message

* Fix unit test

* PR feedback

* Try fixing test

* Edit exception msg

* Expand unit test to include pkg prerelease

* Update core/dbt/deps/registry.py

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>

Co-authored-by: Doug Beatty <44704949+dbeatty10@users.noreply.github.com>
2022-08-19 23:13:03 +02:00
Doug Beatty
d80de82316 Update "Homepage" link for dbt-tests-adapter on PyPI (#5678) 2022-08-18 06:27:30 -06:00
Mila Page
0d02446e07 Change postgres name truncation logic to be overridable. (#5656)
* Change postgres name truncation logic to be overridable. Add exception with debugging instructions.

* Add changelog.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-08-18 00:52:43 -07:00
Chenyu Li
a9e71b3907 fix multiple args for ref and source (#5635)
* fix multiple args for ref and source

* add test for support multi part ref and source
2022-08-17 14:13:32 -07:00
Nathaniel May
739fb98d0e Print more information on log line interop test failures (#5659)
Print more information on log line interop test failures
2022-08-16 21:30:10 +01:00
Elize Papineau
348769fa80 Fix/incremental column precision changes (#5395)
* Only consider schema change when column cannot be expanded

* Add test for column shortening

* Add changelog entry

* Move test from integration to adapter tests

* Remove print statement

* add on_schema_change
2022-08-12 14:54:29 -07:00
ilanbenb
7efb6ab62d Incremental model show reason for on_schema_change fail failures (#5505)
* show reason for schema change failures

When the incremental model fails, I do not get the context I need to easily fix my discrepency.
Adding more info

* Update on_schema_change.sql

Fix identation

* Added changie changes

Added changie changes

* Update on_schema_change.sql

Trim whitespaces

* Update on_schema_change.sql

Log message text  enhancement
2022-08-12 10:07:30 -07:00
Vyacheslav
a3b018fd3b Extended validations for the project names (#5620) 2022-08-10 16:45:42 -07:00
varun-dc
4d6208be64 Use sys.exit instead of exit (#5627)
* Use sys.exit instead of exit

* Add changelog
2022-08-09 10:22:36 -07:00
Gerda Shank
3aab9befcf CT-729 Include schema model config in unrendered config (#5344)
* Pass patch_config_dict to build_config_dict when creating
unrendered_config

* Add test case for unrendered_config

* Changie

* formatting, fix test

* Fix test so unrendered config includes docs config
2022-08-09 12:49:29 -04:00
Léon Stefani
e5ac9df069 Fix postgres handling for unlimited varchars (#5292)
* Fix postgres handling for unlimited varchars

* fix: correctly name varchar

* chore: added changelog entry

* Update .changes/unreleased/Fixes-20220523-103843.yaml

Co-authored-by: Emily Rockman <ebuschang@gmail.com>

Co-authored-by: Emily Rockman <ebuschang@gmail.com>
2022-08-09 09:59:58 -05:00
Emily Rockman
34960d8d61 link changelog to dbt-docs for Docs kind (#5628)
* first pass

* tweaks

* convert to use dbt-docs links in contributors section

* fix eq check

* fix format of contributos prs

* update docs changelog to point back to dbt-docs

* update beta 1.3 docs changelog

* remove optional param

* make issue inclusion conditional on being filled
2022-08-09 09:19:40 -05:00
Callum McCann
94a7cfa58d Adding Metric Helper Functions (#5607)
* Adding helper functions

* adding bad test

* use ResolvedMetricReference

* adding pytest

* adding changie updates

* adding pre-commit changes

Co-authored-by: Chenyu Li <chenyu.li@dbtlabs.com>
2022-08-08 08:37:09 -05:00
Gerda Shank
eb72dbf32a Do not render metrics description field when doing render_data (#5603) 2022-08-05 09:19:46 -04:00
Emily Rockman
9eb411f7b7 bring in new index and add changelog (#5614)
* bring in new index and add changelog

* Update Docs-20220804-134138.yaml
2022-08-04 14:07:18 -05:00
Benoit Perigaud
32415e3659 Add docs as a real node config and support node_color for coloring the DAG (#5397)
* add Optional node_color config in Docs dataclass

* Remove node_color from the original docs config

* Add docs config and input validation

* Handle when docs is both under docs and config.docs

* Add node_color to Docs

* Make docs a Dict to avoid parsing errors

* Make docs a dataclass instead of a Dict

* Fix error when using docs as dataclass

* Simplify generator for the default value

* skeleton for test fixtures

* bump manifest to v7

* + config hierarchy tests

* add show override tests

* update manifest

* Remove node_color from the original docs config

* Add node_color to Docs

* Make docs a Dict to avoid parsing errors

* Make docs a dataclass instead of a Dict

* Simplify generator for the default value

* + config hierarchy tests

* add show override tests

* Fix unit tests

* Add tests in case of incorrect input for node_color

* Rename tests and Fix typos

* Fix functional tests

* Fix issues with remote branch

* Add changie entry

* modify tests to meet standards (#5608)

Co-authored-by: Matt Winkler <matt.winkler@fishtownanalytics.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-08-03 14:31:30 -05:00
Gerda Shank
7886924c07 Comment out line to generate new manifest in test_previous_version_state.py (#5604) 2022-08-03 14:18:48 -04:00
Emily Rockman
40b55ed65a convert to reusable action (#5565)
* convert to reusable action

* fix branch name

* reimplemented changelog

* update to use workflow

* fix typo

* move def

* inherit secrets

* send in comment/label

* specify GITHUB_TOKEN

* Add automated changelog yaml from template for bot PR

* Delete Dependency-20220801-193810.yaml

* Add automated changelog yaml from template for bot PR

* remove dummy changelog

* remove token

* rename file

* point to main

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-08-03 11:33:11 -05:00
Emily Rockman
4f5b9e686c Store when default env vars are used in manifest (#5589)
* WIP

* handle defauly env vars

* fix typo

* add changelog

* small fixes

* add constants.py file
2022-08-02 20:53:11 -05:00
Emily Rockman
95284aff68 rename .github readme (#5597) 2022-08-01 19:22:26 -05:00
kadero
063ff9c254 Add defer to docs and compile commands (#4514)
* Add defer to docs and compile commands
Add docs generate defer test
Fix CLA check
Add compile defer test

* Update changelog

* Restore changelog

* Add changie entry

* Move defer_to_manifest to CompileTask

* Add check to to verify defer works as expected

* Add assert
2022-08-01 14:38:08 -07:00
Vyacheslav
26b33e668d use MethodName.File when value ends with .csv (#5581)
* [CT-953] [Feature] Support for .csv files when using file selectors(for seed)

* Added Changelog entry for issue-5578

* Added Unit tests
2022-08-01 14:32:58 -07:00
Jeremy Cohen
26ac9d57d0 Convert git deps to local, faster tests (#5515) 2022-07-30 14:10:57 +02:00
github-actions[bot]
7bd861a351 Bumping version to 1.3.0b1 and generate changelog (#5582)
* Bumping version to 1.3.0b1 and generate CHANGELOG

* Update Docker versions for adapters

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-07-29 11:59:12 -04:00
Chenyu Li
15c97f009a fix passing in Rlock error in rpc (#5580) 2022-07-29 07:46:08 -07:00
Leo Folsom
5153023100 use MethodName.File when value ends with .py (#5295) 2022-07-29 07:33:53 -07:00
Emily Rockman
c879083bc9 add info on basics of using actions (#5576) 2022-07-29 08:20:00 -05:00
Chenyu Li
05bf27c958 add changelog from dbt-docs (#5577) 2022-07-28 15:49:35 -07:00
Chenyu Li
a7ff003d4f python model beta feature(#5421)
* Python model beta version with update to manifest that renames `raw_sql` and `compiled_sql` to `raw_code` and `compiled_code`
Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Ian Knox <ian.knox@dbtlabs.com>
Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>
2022-07-28 11:42:59 -07:00
leahwicz
2547e4f55e Add changelog and whitespace fix to version bump Action (#5563)
* Add changelog and whitespace fix to version bump Action

* Fixing whitespace

* Remove tabs

* Update .github/workflows/version-bump.yml

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>

* Update .github/workflows/version-bump.yml

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>

* Update .github/workflows/version-bump.yml

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>

* Update .github/workflows/version-bump.yml

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>

* Updating per comments

* Fix whitespace

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-07-28 14:08:03 -04:00
Gerda Shank
b43fc76701 Fix handling of top-level exceptions (#5560) 2022-07-27 23:52:17 -04:00
Jeremy Cohen
48464a22a4 Proposed updates to issue "wayfinder" (#5426)
* Propose updates to issue wayfinder

* Updating bug template with clearer description

* Updated link to new troubleshooting spot

* Updating Cloud messaging

* Adding required fields and dbt versions

* Fixed whitespace

Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-07-27 22:25:34 -04:00
Vyacheslav
c3891d78e4 [CT-700] [Bug] Logging tons of asterisks for sensitive env vars (#5518)
* [CT-700] [Bug] Logging tons of asterisks when sensitive env vars are missing

* [CT-700][Bug] Added changelog entry

* Updated the changelog body message
2022-07-27 11:40:32 -05:00
Nicholas A. Yager
69ce6779e1 Improve CompilationException messaging for generic test Jinja rendering (#5393)
* feat: Improve generic test UndefinedMacroException message

The error message rendered from the `UndefinedMacroException` when
raised by a TestBuilder is very vague as to where the problem is
and how to resolve it. This commit adds a basic amount of
information about the specific model and column that is
referencing an undefined macro.

Note: All custom macros referenced in a generic test config will
raise an UndefinedMacroException as of v0.20.0.

* feat: Bubble CompilationException into schemas.py

I realized that this exception information would be better if
CompilationExceptions inclulded the file that raised the exception.
To that end, I created a new exception handler in `_parse_generic_test`
to report on CompilationExceptions raised during the parsing of
generic tests. Along the way I reformatted the message returned
from TestBuilder to play nicely with the the existing formatting of
`_parse_generic_test`'s exception handling code.

* feat: Add tests to confirm CompileException

I've added a basic test to confirm that the approriate
CompilationException when a custom macro is referenced
in a generic test config.

* feat: Add changie entry and tweak error msg

* Update .changes/unreleased/Under the Hood-20220617-150744.yaml

Thanks to @emmyoop for the recommendation that this be listed as a Fix change instead of an "Under the Hood" change!

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>

* fix: Simplified Compliation Error message

I've simplified the error message raised during a Compilation Error
sourced from a test config. Mainly by way of removing tabs and newlines
where not required.

* fix: Convert format to fstring in schemas

This commit moves a format call to a multiline fstring in the
schemas.py file for CompilationExceptions.

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-07-27 09:41:22 -05:00
Emily Rockman
a206cfce65 add readme to .github (#5487)
* add readme to .github

* more changes to readme

* improve docs

* more readme tweaks

* add more docs

* incorporate feedback

* removed section with no info
2022-07-25 16:16:36 -05:00
Emily Rockman
3f54f30349 Remove markupsafe pin (#5507)
* update markupsafe pin

* add changelog

* completely remove markupsafe pin
2022-07-25 09:47:25 -05:00
Matthew McKnight
1071a4681d reformat changie.yaml to ignore dependabot (#5508)
* reformat changie.yaml to ignore dependabot

* Removed modifled file from PR

* Removed modifled file from PR
2022-07-22 09:45:37 -05:00
Gerda Shank
2548ba9936 Refactoring of incremental materialization (#5359) 2022-07-21 14:11:23 -04:00
Nathaniel May
999ed0b74c postgres: add exponential backoff to connection retries (#5503)
add exponential backoff to postgres connection retries
2022-07-21 13:10:52 -04:00
Emily Rockman
eef7bca005 snyk automation plus bot changelog consolidation (#5479)
* first pass at snyk changelog entry

* refactor for single workflow for all bot PRs

* exclude snyk from contributors list

* point action to branch temporarily

* replace quotes

* point to released tag
2022-07-20 17:48:35 -05:00
Gerda Shank
5686cab5a0 Bump mashumaro from 2.9 to 3.0.3 in /core (#5118)
* add pyyaml as a setup requirement
2022-07-20 17:15:51 -04:00
dependabot[bot]
99bc292588 Bump mypy from 0.961 to 0.971 (#5495)
* Bump mypy from 0.961 to 0.971

Bumps [mypy](https://github.com/python/mypy) from 0.961 to 0.971.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.961...v0.971)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-07-19 21:37:49 -04:00
Emily Rockman
a1ee348a6f jinja2 v3 upgrade (#5465)
* update version

* ignore mypy for now

* add changelog
2022-07-19 16:16:31 -05:00
Tomás Farías Santana
2048a1af6f [CT-472] feat: Retrying method for acquiring connection handles (#5432)
Add reusable function for retrying adapter connections. Utilize said function to add retries for Postgres (and Redshift).
2022-07-19 14:55:55 -04:00
Emily Rockman
71223dc253 add timeouts to integration tests (#5481)
* add timeout to integration tests

* add timeout to all jobs in workflow
2022-07-19 10:31:46 -05:00
Emily Rockman
e03d35a9fc Fix: Rename try methods to strict (#5477) (#5478)
* rename strict methods

* add changelog

Co-authored-by: Jeremy Yeo <jeremyyeo@users.noreply.github.com>
2022-07-15 09:38:21 -05:00
github-actions[bot]
f988f76fcc Bumping version to 1.3.0a1 (#5463)
* Bumping version to 1.3.0a1

* Remove whitespace

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-07-12 14:17:06 -04:00
Emily Rockman
0cacfd0f88 cleanup changelog after cutting 1.2.latest branch (#5462) 2022-07-12 11:05:50 -05:00
Matthew McKnight
c25260e5dd Add Grant SQL Macros (#5369)
* init push or ct-660 work

* changes to default versions of get_show_grant_sql and get_grant_sql

* completing init default versions of all macros being called for look over and collaboration

* minor update to should_revoke

* post pairing push up (does have log statements to make sure we remove)

* minor spacing changes

* minor changes, and removal of logs so people can have clean grab of code

* minor changes to how get_revoke_sql works

* init attempt at applying apply_grants to all materialzations

* name change from recipents -> grantee

* minor changes

* working on making a context to handle the diff gathering between grant_config and curreent_grants to see what needs to be revoked, I know if we assign a role, and a model becomes dependent on it we can't drop the role now still not seeing the diff appear in log

* removing logs from most materializations to better track diff of grants generation logs

* starting to build out postgres get_show_grant_sql getting empty query errors hopefully will clear up as we add the other postgres versions of macros and isn't a psycopg2 issue as indicated by searching

* 6/27 eod update looking into diff_grants variable not getting passed into get_revoke_sql

* changes to loop cases

* changes after pairing meeting

* adding apply_grants to create_or_replace_view.sql

* models are building but testing out small issues around revoke statement never building

* postgrest must fixes from jeremy's feedback

* postgres minor change to standarize_grants_dict

* updating after pairing with dough and jeremey incorporating the new version of should revoke logic.

* adding  ref of diff_of_two_dicts to base keys ref

* change of method type for standardize_grants_dict

* minor update trying to fix unit test

* changes based on morning feedback

* change log message in default_apply_grants macro

* CT-808 grant adapter tests (#5447)

* Create initial test for grants

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>

* rename grant[privilege] -> grant_config[privilege]

* postgres macro rename to copy_grants

* CT-808 more grant adapter tests (#5452)

* Add tests for invalid user and invalid privilege

* Add more grant tests

* Macro touch ups

* Many more tests

* Allow easily replacing privilege names

* Keep adding tests

* Refactor macros to return lists, fix test

* Code checks

* Keep tweaking tests

* Revert cool grantees join bc Snowflake isnt happy

* Use Postgres/BQ as standard for standardize_grants_dict

* Code checks

* add missing replace

* small replace tweak,  add additional dict diffs

* All tests passing on BQ

* Add type cast to test_snapshot_grants

* Refactor for DRYer apply_grants macros

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>

* update to main, create changelog, whitespace fixes

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
2022-07-11 11:58:41 -05:00
Batuhan Taskaya
c521fa6b74 Add --target-path as a CLI option. (#5402) 2022-07-07 12:49:25 -04:00
Emily Rockman
f304b4b2da add new index file for dbt-docs for 1.2.0 release (#5446)
* add new index file for dbt-docs for 1.2.0 release

* add PR number to changelogs
2022-07-06 16:12:38 -05:00
Drew Banin
064d890172 (#4884) Add support for ratio metrics (#5027)
* wip

* More support for ratio metrics

* Formatting and linting

* Fix unit tests

* Support disabling metrics

* mypy

* address all TODOs

* make pypy happy

* wip

* checkpoint

* refactor, remove ratio_terms

* flake8 and unit tests

* remove debugger

* quickfix for filters

* Experiment with functional testing for 'expression' metrics

* reformatting slightly

* make file and mypy fix

* remove config from metrics - wip

* add metrics back to context

* adding test changes

* fixing test metrics

* revert name audit

* pre-commit fixes

* add changelog

* Bumping manifest version to v6 (#5430)

* Bumping manifest version to v6

* Adding manifest file for tests

* Reverting unneeded changes

* Updating v6

* Updating test to add metrics field

* Adding changelog

* add v5 to backwards compatibility

* Clean up test_previous_version_state, update for v6 (#5440)

* Update test_previous_version_state for v6. Cleanup

* Regenerate, rm breakpoint

* Code checks

* Add assertion that will fail when we bump manifest version

* update tests to automatically tests all previous versions

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Callum McCann <cmccann51@gmail.com>
Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-07-06 16:01:14 -05:00
Paolo Quadri
febbd978b5 Fix/fix quotes behaviour in snapshots (#5389)
* fix: add quotes to relation

* fix: add quotes correctly

* chore: reset main.py

* chore: reset main.py from master

* chore: newline

* chore: changie
2022-07-06 16:30:19 -04:00
dependabot[bot]
0d7e87fac6 Bump mypy from 0.942 to 0.961 (#5337)
* Bump mypy from 0.942 to 0.961

Bumps [mypy](https://github.com/python/mypy) from 0.942 to 0.961.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.942...v0.961)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template

* Fixed deprecated abstractclassmethod caught by new version of mypy

* Fixed deprecated abstractclassmethod not caught by mypy

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: Ian Knox <ian.knox@dbtlabs.com>
2022-07-06 16:25:05 -04:00
Volkan Gürel
3500528506 Add inheritance to materialization macro resolution (#5348)
* Add inheritance to materialization macro resolution

* Add changelog entry

* Address PR feedback
2022-07-06 13:56:52 -04:00
Joe Markiewicz
c42221fcf3 feature/deps-regex-semver (#5370)
* feature/deps-regex-semver

* pre-commit fixes

* applying review updates
2022-07-06 10:56:07 -04:00
dependabot[bot]
f49f28c331 Update colorama requirement from <0.4.5,>=0.3.9 to >=0.3.9,<0.4.6 in /core (#5388)
* Update colorama requirement in /core
2022-07-05 14:46:56 -05:00
dependabot[bot]
dc964c43d9 Bump black from 22.3.0 to 22.6.0 (#5420)
* Bump black from 22.3.0 to 22.6.0
2022-07-05 14:02:15 -05:00
Peter Debelak
60e491b3c1 Improve pluralizations for Documentation and SqlOperation NodeTypes (#5356)
* Improve pluralizations for Documentation and SqlOperation NodeTypes

Previously these were `docss` and `sqlss` which leaves something to be
desired.

* Add changie changelog entry for pluralization change

* Slighly simplify node type pluralization tests

* Update node type names for sql and docs so they match pluralizations
2022-06-30 16:15:07 -04:00
Jeremy Cohen
3bfce2bac9 Move data type macros into dbt-core (#5428)
* Move data type macros into dbt-core

* Changelog entry

* Code quality checks. Fix type_float
2022-06-30 19:46:07 +02:00
Darin Douglass
d63ad4cd82 [CT-679] flip logic around reset color detection (#5394) 2022-06-29 17:28:01 -04:00
Jeremy Cohen
d5608dca32 Follow-up to #5334 (#5382)
* Follow-up to secret rendering changes

* Update changelog entries

* PR feedback
2022-06-28 10:06:12 +02:00
Mila Page
e7031f2d74 Ct 488/migrate invalid model tests (#5391)
Migrate 006 dependency tests to the new framework
2022-06-24 12:05:41 -04:00
github-actions[bot]
68a2996788 Bumping version to 1.2.0b1 (#5406)
* Bumping version to 1.2.0b1

* Add changelog

* Remove whitespace

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: Leah Antkiewicz <leah.antkiewicz@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-06-24 10:10:39 -04:00
leahwicz
f5f0a7f908 Removing old script from bumpversion (#5405) 2022-06-24 09:42:48 -04:00
Jeremy Yeo
1cfc0851ca [Fix]: remove duplicate key checking (#5403)
* remove duplicate key checking

* add changelog
2022-06-23 15:24:15 -04:00
Ulises Ojeda
d257d0b44c Early return from dbt init if no available adapters (#5366)
* Exit from dbt init if no available adapters

* adding chnagie change

* fixing init_tests
2022-06-17 09:42:37 -07:00
Matthew McKnight
f8d347e5f8 deleting scaffold and create_adater_plugin.py file from scripts section of core as they a… (#5117)
* deleting scaffold and .py file from scripts section of core as they are either deprecated or will live outside of core

* adding changelog

* removing files that shouldn't be there

* update changelog to have link to new scaffold

* readding the original script file but changing its output ot be a print statement and leave comment that also points to the new scaffold

* sentence change
2022-06-16 14:00:08 -05:00
Doug Beatty
a02db03f45 Lift + shift for cross-db macros (#5298)
* Initialize lift + shift, dateadd + datediff

* Placeholder changelog for now

* Lift and shift cross-database macros, fixtures, and tests from dbt-utils

* Switch namespace from `dbt_utils` to `dbt`

* Remove unreferenced variable

* Remove conflicting definition of current_timestamp()

* Trim leading and trailing whitespace

* Apply Black formatting

* Remove unused import

* Remove references to other profiles

* Update .changes/unreleased/Features-20220518-114604.yaml

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>

* Kick out the `type_*` tests

* Kick out the `type_*` macros

* Kick out the `current_timestamp` tests

* Kick out the `current_timestamp` macros

* Kick out the `current_timestamp` macros

* Kick out the `type_*` macros

* Use built-in adapter functionality for converting string datatypes

* Move comment above macro for postgres__any_value

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2022-06-16 20:07:36 +02:00
Jeremy Cohen
6e8388c653 Declare compatibility for previous artifact versions (#5346)
* Add functional test

* Add is_compatible_version logic

* Add changelog entry

* Fix mypy
2022-06-16 12:19:18 +02:00
jared-rimmer
6572b7e0a5 Prettify duration message at end of execution (#5364)
* Prettify duration message at end of execution
2022-06-15 12:28:55 -07:00
Matthew McKnight
26bb5c3484 Adapters README (doc days of winter) (#5332)
* init docs write up

* updating based on feedback from gerda

* minor sentence structure changes

* minor changes after feedback
2022-06-15 10:18:07 -05:00
leahwicz
83f4992073 Adding scheduled CI testing Action (#5349)
* Adding scheduled CI testing Action

* Fixing malformed message

* Fixing messaging quotes

* Update to not fail fast

* Reordered branches

* Updating job name

* Removed PR trigger used for testing
2022-06-14 13:24:52 -04:00
dependabot[bot]
8392023e9f Bump python from 3.10.3-slim-bullseye to 3.10.5-slim-bullseye in /docker (#5367)
* Bump python from 3.10.3-slim-bullseye to 3.10.5-slim-bullseye in /docker

Bumps python from 3.10.3-slim-bullseye to 3.10.5-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add automated changelog yaml from template

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-06-14 11:34:42 -04:00
Matthew McKnight
309efaa141 remove script for snowflake oauth reset as its been moved to snowflake (#5362)
* remove script for snowflake oauth reset as its been moved to snowflake

* changelog entry
2022-06-14 09:45:40 -05:00
Chenyu Li
a5993fc866 lower networkx for py37 (#5264) 2022-06-13 12:13:32 -07:00
Chenyu Li
5b1bc72ae1 python model adr (#5345)
* add python model adr first version
2022-06-13 07:54:55 -07:00
Greg Roodt
72b6a80b07 Remove duplicate dbt script entry (#5304)
* Remove duplicate dbt script entry.

* changie
2022-06-08 16:14:37 -07:00
leahwicz
e48f7ab32e Fixing Windows color regression (#5327)
* Fixing Windows color regression

* Cleaning up logic

* Consolidating logic to the logger

* Cleaning up vars

* Updating comment

* Removing unused import

* Fixing whitespace

* Adding changelog
2022-06-07 09:06:02 -04:00
Jeremy Cohen
16dc2be556 Update context readme, small code cleanup (#5334) 2022-06-06 23:39:34 +02:00
Ian Knox
eea872c319 New ancestor/descendant algo (#5326)
* New ancestor/descendant algo

* changelog
2022-06-02 10:46:01 -07:00
Gerda Shank
189c06dbb1 CT-710 fix test graph selection (#5324)
* Fix test_graph_selection so it can run separately

* Changie
2022-06-01 12:01:10 -04:00
Kyle Wigley
74662d1527 fix pip upgrade step in CI for windows (#5320)
* fix pip upgrade step in CI for windows

* Changie

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2022-06-01 11:24:05 -04:00
Mila Page
75f3e8cb74 Add notes on invoking Python methods in adapter macros (#5306)
Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-05-31 08:55:30 -07:00
Jeremy Cohen
aeee1c23a6 Tidying up materialization logic: relation names, cache loading, etc (#5221)
* Clean up existing_relation, load_relation,  etc

* Add changelog entry

* Empty commit, retrigger CI
2022-05-20 18:02:14 +02:00
Gerda Shank
e50678c914 Ct-581 grants as configs (#5230)
* Handle 'grants' in NodeConfig, with correct merge behavior

* Fix a bunch of tests

* Add changie

* Actually add the test

* Change to default replace of grants with '+' extending them

* Additional tests, fix config_call_dict handling

* Tweak _add_config_call to remove unnecessary isinstance checks
2022-05-19 14:50:47 -04:00
Josh Wills
ae62f5708c Switch the Makefile to use the default installed Python version instead of py38 for local testing (#5269)
* Setting up an env var to use to override the tox python variable used for local dev

* Switch over to py-based tox envs instead of the py38 ones to be friendly to dbt-core devs who don't work at dbt Labs

* changie
2022-05-19 12:50:26 -04:00
Gerda Shank
cda88d1948 CT-159 Remove docs file from manifest when deleting doc node (#5270)
* Convert partial parsing docs tests

* Failing test

* Remove doc file from manifest when doc node is removed

* Changie
2022-05-19 11:37:45 -04:00
Elize Papineau
e7218d3e99 Truncate relation names when appending a suffix (#4921)
* Truncate relation names when appending a suffix that will result in len > 63 characters using make_temp_relation and make_backup_relation macros

* Remove timestamp from suffix appended to backup relation

* Add changelog entry

* Implememt make_relation_with_suffix macro

* Add make_intermediate_relation macro that controls _tmp relation creation in table and view materializations to delienate from database- and schema-less behavior of relation returned from make_temp_relation

* Create backup_relation at top of materialization to use for identifier

* cleanup

* Add dstring arg to make_relation_with_suffix macro

* Only reference dstring in conditional of make_relation_with_suffix macro

* Create both a temp and intermediate relation, update preexisting_temp_relation to preexisting_intermediate_relation

* Migrate test updates to new test location

* Remove restored tmp.csv

* Revert "Remove restored tmp.csv"

This reverts commit 900c9dbcad9a1e6a5a6737c84004504bfdd9926f.

* Actually remove restored tmp.csv
2022-05-19 13:57:15 +02:00
leahwicz
2c42fb436c Creating ADR for versioning and branching strategy (#4998)
* Creating ADR for versioning and branching strategy

* Fixing image link

* Grammar clean-up

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Grammar clean-up

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Update docs/arch/adr-003-versioning-branching-strategy.md

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Update docs/arch/adr-003-versioning-branching-strategy.md

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Update docs/arch/adr-003-versioning-branching-strategy.md

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Update docs/arch/adr-003-versioning-branching-strategy.md

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Update docs/arch/adr-003-versioning-branching-strategy.md

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Update docs/arch/adr-003-versioning-branching-strategy.md

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Update docs/arch/adr-003-versioning-branching-strategy.md

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Update docs/arch/adr-003-versioning-branching-strategy.md

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>

* Updating Outside Scope section

* Changing from using type to stage

* Adding section on getting changes into certain releases

* Changed stages to phases

* Some wording updates

* New section for branching pros and cons

* Clarifying version bump statement

* A few minor comment fix ups

* Adding requirement to define released

* Updating to completed!

Co-authored-by: Stu Kilgore <stuart.kilgore@gmail.com>
2022-05-18 23:12:20 -04:00
Gerda Shank
a9e1a0e00a Tweak test to avoid set ordering problem (#5272) 2022-05-18 17:28:48 -04:00
Jeremy Cohen
0d8e061a3d Add dbt Core roadmap as of May 2022 (#5246) 2022-05-15 10:47:55 +02:00
Stu Kilgore
7532420eef Fix macro modified from previous state with pkg (#5224)
* Fix macro modified from previous state with pkg

When iterating through nodes to check if any of its macro dependencies
have been modified, the state selector will first check all upstream
macro dependencies before returning a judgement.
2022-05-13 13:04:15 -05:00
Josh Wills
03b17ff401 Add support for File Selectors and add file selectors to the default method selector list (#5241)
* Add a new selector method for files and add it to the default method selection criteria if the given selector has a . in it but no path separators

* Add a file: selector method to the default selector methods because it will make Pedram happy

* changie stuff
2022-05-13 09:39:55 -07:00
Tomás Farías Santana
fc1fc2d5e9 fix: Avoid access to profile when calling str(UnsetProfileConfig) (#5209)
* fix: Avoid access to profile when calling str(UnsetProfileConfig)

dbt.config.UnsetProfileConfig inherits __str__ from
dbt.config.Project. Moreover, UnsetProfileConfig also raises an
exception when attempting to access unset profile attributes. As
Project.__str__ ultimately calls to_project_config and accesses said
profile attributes, we override to_project_config in
UnsetProfileConfig to avoid accessing the attributes that raise an
exception.

This allows calling str(UnsetProfileConfig) and
repr(UnsetProfileConfig).

Basic unit testing is also included in commit.

* fix: Skip repr for profile fields in UnsetProfileConfig

* chore(changie): Add changie file
2022-05-13 08:36:13 -07:00
Jeremy Yeo
7e43f36bb1 Feature: Add set/zip function to contexts (#5107)
* add set function to contexts

* add zip function to contexts

* add changelog

* add try_ equivalents

* remove defaults

* add tests

* update tests
2022-05-13 10:25:51 -05:00
Jeremy Cohen
72c17c4464 Fix: use adapter.get_columns_in_relation (#5232) 2022-05-11 16:48:25 +02:00
Jeremy Cohen
3996a69861 Fix: column comparison logic for check-strategy snapshots (#5223)
* Add test case

* Update comparison in snapshot_check_all_get_existing_columns

* Add changelog entry
2022-05-10 11:04:56 +02:00
leahwicz
aa8115aa5e Bumping hologram version (#5218)
* Bumping hologram version

* Add automated changelog yaml from template

* Updating issue

* Loosen requirement range

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2022-05-09 15:49:11 -04:00
Ian Knox
ab0c3510eb Revert inaccurate mypy change (#5216) 2022-05-06 09:21:48 -05:00
Ian Knox
4480d05cfb Update mypy to latest and turn on everywhere (#5171) 2022-05-05 12:00:11 -05:00
Gerda Shank
788694ec5b Convert materialization tests to new test framework (#5212) 2022-05-04 13:55:09 -04:00
Nicolas Parot Alvarez
fb5bb7fff3 Improve tracking error logging message (#5211) 2022-05-04 11:00:13 -04:00
Matthew McKnight
c270a77552 propseal for modification to drop_test_schema (#5198)
* propseal for modification to drop_test_schema

* changelog

* remove hard coded run_dbt version and put back previous version of drop_test_schema, add commit to drop_schema
2022-05-03 13:10:02 -05:00
Alex Rosenfeld
a2e040f389 Allow the target name to be set in profile_template.yml (#5184)
* Allow the target name to be set in profile_template.yml
2022-05-03 11:44:40 -05:00
Michael Manganiello
a4376b96d8 seed: Add new macro get_csv_sql (#5207)
new macro `get_csv_sql`
2022-05-03 11:32:24 -05:00
Gerda Shank
ed5df342ca Convert 013_context_vars_tests to context_methods. Move existing cli_vars into context_methods (#5199) 2022-05-02 16:02:37 -04:00
Emily Rockman
96f063e077 update label check (#5194) 2022-05-02 11:51:23 -05:00
leahwicz
ee8f81de6a Adding Skip Changelog label to Version Bump action (#5203) 2022-05-02 12:40:58 -04:00
Emily Rockman
935edc70aa remove reference to unused ok to test label (#5149) 2022-05-02 09:21:17 -05:00
dependabot[bot]
28c44a9be7 Bump ubuntu from 20.04 to 22.04 (#5141)
* Bump ubuntu from 20.04 to 22.04
2022-04-29 15:53:25 -05:00
Stu Kilgore
a2b3602485 Convert list tests to pytest (#5178) 2022-04-28 15:00:39 -05:00
Jeremy Yeo
3733817488 Fix: add warning on duplicated yaml keys (#5146)
* add warning on duplicated yaml keys

* update structure and tests

* fix old test schema file

* add changelog
2022-04-28 09:31:18 -04:00
Jeremy Cohen
c5fb6c275a Update README for dbt-tests-adapter (#5182)
* Update README for dbt-tests-adapter

* Add logo
2022-04-28 15:26:02 +02:00
Gerda Shank
f633e9936f When parsing 'all_sources' should be a list of unique dirs (#5176)
* When parsing 'all_sources' should be a list of unique dirs

* Changie

* Fix some unit tests of all_source_paths

* Convert 039_config_tests

* Remove old 039_config_tests

* Add test for duplicate directories in 'all_source_files'
2022-04-27 21:02:51 -04:00
Gerda Shank
4e57c51c7a Ct-65 metrics names with spaces (#5173)
* Convert existing metrics test

* add non-failing test for names with spaces

* Raise ParsingException if metrics name contains spaces

* Remove old metrics tests
2022-04-27 10:57:32 -04:00
Gary James
6267572ba7 Fix adding new cols to check_cols in snapshots (#4893) 2022-04-26 18:55:14 -04:00
Daniel Diamond
32e1924c3b Add selector method capabilities to selectors (#4827) 2022-04-26 18:52:08 -04:00
Chenyu Li
55af3c78d7 remove extra class and add connection test (#5163)
* remove extra class and add connection test

* add project artifact to avoid breaking other tests

* add comment
2022-04-26 16:07:23 -06:00
Mila Page
bdff19d909 migrate 009_data_tests to new test framework (#5139)
* Fold so-called 'data' test into new framework with new vocabulary to match.
* Add missing files including changelog.
* Remove unneeded Changelog per team policy on test conversions.
* Refactor test code to better use our pytest framework. Strengthen assertions.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-04-26 14:59:27 -07:00
Ben Dowling
f87c7819fb Add itertools to modules (#5140)
* GH hygiene: contributing guide, templates, stalebot (#4967)

* Update contributing guide

* Update issue + PR templates

* Stalebot for all issues, no exceptions

* Update links

* Missed one

* PR feedback

* Update CHANGELOG

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2022-04-26 16:32:06 -05:00
Mila Page
33694f3772 Ct 488/migrate invalid model tests (#5143)
* First test completed.
* Convert and update more test cases.
* Complete test migration and remove old files.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-04-26 13:38:34 -07:00
Emily Rockman
ebfc18408b Tweak triage-label.yml to trigger off issue labels instead of PR labels (#5168)
* fix label check

* fix label filter to go against issues not PRs
2022-04-26 15:25:20 -05:00
Emily Rockman
6958f4f12e add triage label workflow (#5164) 2022-04-26 13:39:09 -05:00
Gerda Shank
1f898c859a Use yaml renderer (with target context) for rendering selectors (#5136)
* Use yaml renderer (with target context) for rendering selectors

* Changie

* Convert cli_vars tests

* Add test for var in profiles

* Add test for cli vars in packages

* Add test for vars in selectors
2022-04-26 11:42:50 -04:00
Jeremy Cohen
ce0bcc08a6 Even more scrubbing (#5152)
* Even more scrubbing

* Changelog entry

* Even more

* remove reduendent scrub

* remove reduendent scrub

* fix encoding issue

* keep scrubbed log in args

Co-authored-by: Chenyu Li <chenyu.li@dbtlabs.com>
2022-04-26 09:35:01 -06:00
leahwicz
d1ae9dd37f Updating backport Action permissions (#5121) 2022-04-25 09:33:49 -04:00
Emily Rockman
31a3f2bdee fix retry logic failures (#5137)
* fix retry logic failures

* changelog

* add tests to make sure data is getting where it needs to

* rename file

* remove duplicate file
2022-04-25 06:08:57 -05:00
Jeremy Cohen
1390715590 GH hygiene: contributing guide, templates, stalebot (#4967)
* Update contributing guide

* Update issue + PR templates

* Stalebot for all issues, no exceptions

* Update links

* Missed one

* PR feedback
2022-04-22 13:57:15 +02:00
Doug Beatty
d09459c980 Restore ability to utilize updated_at for check_cols snapshots (#5077)
* Restore ability to configure and utilize `updated_at` for snapshots using the check_cols strategy

* Changelog entry

* Optional comparison of column names starting with `dbt_`

* Functional test for check cols snapshots using `updated_at`

* Comments to explain the test implementation
2022-04-21 06:56:19 -06:00
Emily Rockman
979e1c74bf add new GHA for dependabot PRs (#5065)
* add new GHA for dependabot PRs

* Add automated changelog entry

* code cleanup

* remove changelog file

* permissions tweak

* Add automated changelog yaml from template

* update commit author

* Add automated changelog yaml from template

* fix formatting, remove changelog

* revert to separate files and comment out changelog check temporarily

* Add automated changelog yaml from template

* add back changelog check, update how commit works

* remove file

* Add automated changelog yaml from template

* WIP update to use PAT

* update PAT name

* remove file

* Add automated changelog yaml from template

* format file with quotes

* delete file

* Add automated changelog yaml from template

* remove extra line

* remove file

* Add automated changelog yaml from template

* Delete Dependencies-20220418-194629.yaml

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
2022-04-20 15:55:58 -05:00
Gerda Shank
7d0fccd63f Convert docs_generate_tests to new framework (#5058) 2022-04-20 11:30:34 -04:00
Emily Rockman
37b8b65aad cleanup changelog files on main after cutting release branch (#5112)
* cleanup cahngelog files on main after release branch was cut

* last file that is backported
2022-04-19 15:24:45 -05:00
Emily Rockman
0211668361 CT-476 convert deprecation tests (#5034)
* first pass at 012 test conversion

* convert 012_deprecation tests

* add logic around dropping schema

* swap exception

* added clarifying comment
2022-04-19 13:07:05 -05:00
leahwicz
f8c8322bb4 Updating backport action to latest (#5082)
* Updating backport action to latest

* Updating to PR trigger with permissions instead

This is a better model for closing down all permissions and just granting what we actually want

* Updating IF when merged and backport label exists

* Changing to only trigger on label being added
2022-04-18 15:36:43 -04:00
Mila Page
14c2bd9959 Ct 488/migrate simple seed (#5060)
* (finally) idiomatically rewrite a class of tests into the new framework.

* Get simple seed mostly working with design tweaks needed.

* Revamp tests to use more of the framework. Fix TODOs

* Complete migration of 005 and remove old files.

* Fix BOM test for Windows and add changelog entry

* Finalize tests in the adapter zone per conversation with Chenyu.

Co-authored-by: Mila Page <versusfacit@users.noreply.github.com>
2022-04-14 13:18:31 -07:00
Emily Rockman
8db6bac1db move deprecation check outside package caching (#5069)
* move deprecation check outside package caching

* add changelog
2022-04-14 14:13:38 -05:00
Joel Labes
080dd41876 Clarify steps to reopen a stale issue (#4802)
I haven't added a message for stale PRs because they're likely to only impact the opening user (who I assume can reopen their own PR) and they're less of a problem. Happy to add that in as well, as well as to take feedback on the specific phrasing here.
2022-04-14 17:50:27 +02:00
Amy Byrum
8e9702cec5 Add updated dbt diagram for readme (#5055) 2022-04-13 14:34:17 -06:00
Michael Manganiello
5ff81c244e Flexibilize MarkupSafe pinned version (#5039)
* Flexibilize MarkupSafe pinned version

The current `MarkupSafe` pinned version has been added in #4746 as a
temporary fix for #4745.

However, the current restrictive approach isn't compatible with other
libraries that could require an even older version of `MarkupSafe`, like
Airflow `2.2.2` [0], which requires `markupsafe>=1.1.1, <2.0`.

To avoid that issue, we can allow a greater range of supported
`MarkupSafe` versions. Considering the direct dependency `dbt-core` has
is `Jinja2==2.11.3`, we can use its pinning as the lower bound, which is
`MarkupSafe>=0.23` [1].

This fix should be also backported this to `1.0.latest` for inclusion in
the next v1.0 patch.

[0] https://github.com/adamantike/airflow/blob/2.2.2/setup.cfg#L125
[1] https://github.com/pallets/jinja/blob/2.11.3/setup.py#L53
2022-04-13 13:44:27 -06:00
github-actions[bot]
cfe81e81fd Bumping version to 1.2.0a1 (#5045)
* Bumping version to 1.2.0a1

* Fixing spacing issue

Co-authored-by: Github Build Bot <buildbot@fishtownanalytics.com>
Co-authored-by: leahwicz <60146280+leahwicz@users.noreply.github.com>
2022-04-12 17:00:07 -04:00
leahwicz
365414b5fc Bumping manifest schema to v5 (#5032)
* Bumping manifest schema to v5

* Adding changelog
2022-04-12 16:06:24 -04:00
Nathaniel May
ec46be7368 Perf regression testing - overhaul of readme and runner (#4602) 2022-04-12 16:00:55 -04:00
Stu Kilgore
f23a403468 Update version output and logic (#5029)
Update version output and logic
2022-04-12 14:36:55 -05:00
Benoit Perigaud
15ad34e415 Add selected_resources to the Jinja context (#5001)
* Add selected_resources in the Jinja context

* Add tests for the Jinja variable selected_resources

* Add Changie entry for the addition of selected_resources

* Move variable to the ProviderContext

* Move selected_resources from ModelContext to ProviderContext

* Update unit tests for context to cater for the new selected_resources variable

* Move tests to a Class where tests are run after a dbt build
2022-04-12 10:25:45 -06:00
Jeremy Cohen
bacc891703 Add experimental cache_selected_only config (#5036)
* cache schema for selected models

* Create Features-20220316-003847.yaml

* rename flag, update postgres adapter

rename flag to cache_selected_only, update postgres adapter: function _relations_cache_for_schemas

* Update Features-20220316-003847.yaml

* added test for cache_selected_only flag

* formatted as per pre-commit

* Add breaking change note for adapter plugin maintainers

* Fix whitespace

* Add a test

Co-authored-by: karunpoudel-chr <poudel.karun@gmail.com>
Co-authored-by: karunpoudel-chr <62040859+karunpoudel@users.noreply.github.com>
2022-04-12 18:04:39 +02:00
Emily Rockman
a2e167761c add more complete logic around changelog contributors section (#5037)
* add more complete logic around changelog contributors section

* add instructions for future core team members

* Update .changie.yaml
2022-04-12 10:35:21 -05:00
Emily Rockman
cce8fda06c Add enabled as a source config (#5008)
* initial pass at source config test w/o overrides

* Update tests/functional/sources/test_source_configs.py

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>

* Update tests/functional/sources/test_source_configs.py

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>

* tweaks from feedback

* clean up some test logic - add override tests

* add new fields to source config class

* fix odd formatting

* got a test working

* removed unused tests

* removed extra fields from SourceConfig class

* fixed next failing unit test

* adding back missing import

* first pass at adding source table configs

* updated remaining tests to pass

* remove source override tests

* add comment for config merging

* changelog

* remove old comments

* hacky fix for permission test

* remove unhelpful test

* adding back test file that was accidentally deleted

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
Co-authored-by: Nathaniel May <nathaniel.may@fishtownanalytics.com>
Co-authored-by: Chenyu Li <chenyu.li@dbtlabs.com>
2022-04-12 10:27:29 -05:00
leahwicz
dd4ac1ba4a Updating tests and doc to support Python 3.10 (#5025)
* Updating tests and doc to support Python 3.10

* Single quotes needed for python version matrix

* Adding changelog
2022-04-12 10:52:44 -04:00
Sung Won Chung
401ebc2768 Smart Source Freshness Runs (#4256)
* first draft

* working selector code

* remove debug print logs

* copy test template

* add todo

* smarter depends on graph searching notes

* add excluded source children nodes

* remove prints and clean up logger

* opinionated fresh node selection

* better if handling

* include logs with meaningul info

* add concurrent selectors note

* cleaner logging

* Revert "Merge branch 'main' of https://github.com/dbt-labs/dbt into feature/smart-source-freshness-runs"

This reverts commit 7fee4d44bf, reversing
changes made to 17c47ff42d.

* tidy up logs

* remove comments

* handle criterion that does not match nodes

* use a blank set instead

* Revert "Revert "Merge branch 'main' of https://github.com/dbt-labs/dbt into feature/smart-source-freshness-runs""

This reverts commit 71125167a1.

* make compatible with rc and new logger

* new log format

* new selector flag name

* clarify that status needs to be correct

* compare current and previous state

* correct import

* add current state

* remove print

* add todo

* fix error conditions

* clearer refresh language

* don't run wasteful logs

* remove for now

* cleaner syntax

* turn generator into set

* remove print

* add fresh selector

* data bookmarks matter only

* remove exclusion logic for status

* keep it DRY

* remove unused import

* dynamic project root

* dynamic cwd

* add TODO

* simple profiles_dir import

* add default target path

* headless path utils

* draft work

* add previous sources artifact read

* make PreviousState aware of t-2 sources

* make SourceFreshSelectorMethod aware of t-2 sources

* add archive_path() for t-2 sources to freshness.py

* clean up merged branches

* add to changelog

* rename file

* remove files

* remove archive path logic

* add in currentstate and previousstate defaults

* working version of source fresher

* syntax source_fresher: works

* fix quoting

* working version of target_path default

* None default to sources_current

* updated source selection semantics

* remove todo

* move to test_sources folder

* copy over baseline source freshness tests

* clean up

* remove test file

* update state with version checks

* fix flake tests

* add changelog

* fix name

* add base test template

* delegate tests

* add basic test to ensure nothing runs

* add another basic test

* fix test with copy state

* run error test

* run warn test

* run pass test

* error handling for runtime error in source freshness

* error handling for runtime error in source freshness

* add back fresher selector condition

* top level selector condition

* add runtime error test

* testing source fresher test selection methods

* fix formatting issues

* fix broken tests

* remove old comments

* fix regressions in other tests

* add Anais test cases

* result selector test case

Co-authored-by: Matt Winkler <matt.winkler@fishtownanalytics.com>
2022-04-12 15:08:06 +02:00
Emily Rockman
83612a98b7 cache after retrying instead of while retrying (#5028) 2022-04-11 19:53:11 -05:00
Leopoldo Araujo
827eae2750 Added no-print flag (#4854)
* Added no-print flag

* Updated changelog

* Updated changelog

* Removed changes from CHANGELOG.md

* Updated CHANGELOG.MD with changie

* Update .changes/unreleased/Features-20220408-114118.yaml

Co-authored-by: Emily Rockman <ebuschang@gmail.com>

Co-authored-by: Emily Rockman <ebuschang@gmail.com>
2022-04-11 13:48:34 -05:00
Emily Rockman
3a3bedcd8e Update index file for docs generation (#4995)
* Update index file for docs generation

* add changelog entries
2022-04-11 11:31:03 -05:00
Stu Kilgore
c1dfb4e6e6 Convert --version tests to pytest (#5026)
Convert --version tests to pytest
2022-04-11 11:04:45 -05:00
Gerda Shank
5852f17f0b Fix hard_delete_snapshot test to do the right thing. (#5020) 2022-04-08 16:18:01 -04:00
dependabot[bot]
a94156703d Bump black from 22.1.0 to 22.3.0 (#4972)
* Bump black from 22.1.0 to 22.3.0
2022-04-08 15:10:36 -05:00
Ian Knox
2b3fb7a5d0 updated docker readme CT-452 (#5018) 2022-04-08 14:30:25 -05:00
Ian Knox
5f2a43864f Decouple project creation logic from tasks CT-299 (#4981) 2022-04-08 14:28:37 -05:00
Ian Knox
88fbc94db2 added git-blame-ignore-revs file (#5019) 2022-04-08 14:20:43 -05:00
Chenyu Li
6c277b5fe1 make graph_selection tests just checking selection (#5012)
* make graph_selection tests just checking selection

* use util function
2022-04-08 11:04:54 -06:00
Chenyu Li
40e64b238c adapter_methods (#4939)
* adapter_methods

* fix fixture scope

* update table compare method

* remove unneeded part

* update test name and comment
2022-04-08 08:32:21 -06:00
Ian Knox
581bf51574 updated event message (#5011) 2022-04-08 09:12:49 -05:00
Gerda Shank
899b0ef224 Remove TableComparison and convert existing calls to use dbt.tests.util (#4986) 2022-04-07 13:04:03 -04:00
Matthew McKnight
3ade206e86 init push up of converted unique_key tests (#4958)
* init push up of converted unique_key tests

* testing cause of failure

* adding changelog entry

* moving non basic test up one directory to be more broadly part of adapter zone

* minor changes to the bad_unique_key tests

* removed unused fixture

* moving tests to base class and inheriting in a simple class

* taking in chenyu's changes to fixtures

* remove older test_unique_key tests

* removed commented out code

* uncommenting seed_count

* v2 based on feedback for base version of testing, plus small removal of leftover breakpoint

* create incremental test directory in adapter zone

* commenting out TableComparision and trying to implement check_relations_equal instead

* remove unused commented out code

* changing cast for date to fix test to work on bigquery
2022-04-07 11:29:52 -05:00
agoblet
58bd750007 add DO_NOT_TRACK environment variable support (#5000) 2022-04-07 11:45:29 -04:00
Matthew McKnight
0ec829a096 include directory README (#4685)
* start of a README for the include directory

* minor updates

* minor updates after comments from gerda and emily

* trailing space issue?

* black formatting

* minor word change

* typo update

* minor fixes and changelog creation

* remove changelog
2022-04-06 11:53:59 -05:00
Emily Rockman
7f953a6d48 [CT-352] catch and retry malformed json (#4982)
* catch None and malformed json reponses

* add json.dumps for format

* format

* Cache registry request results. Avoid one request per version

* updated to be direct in type checking

* add changelog entry

* add back logic for none check

* PR feedback: memoize > global

* add checks for expected types and keys

* consolidated cache and retry logic

* minor cleanup for clarity/consistency

* add pr review suggestions

* update unit test

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2022-04-05 10:44:00 -05:00
Snyk bot
0b92f04683 [Snyk] Security upgrade python from 3.9.9-slim-bullseye to 3.10.3-slim-bullseye (#4963)
* fix: docker/Dockerfile to reduce vulnerabilities

The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-DEBIAN11-EXPAT-2403512
- https://snyk.io/vuln/SNYK-DEBIAN11-EXPAT-2406127
- https://snyk.io/vuln/SNYK-DEBIAN11-OPENSSL-2388380
- https://snyk.io/vuln/SNYK-DEBIAN11-OPENSSL-2426309
- https://snyk.io/vuln/SNYK-DEBIAN11-OPENSSL-2426309

* add changelog entry

Co-authored-by: Nathaniel May <nathaniel.may@fishtownanalytics.com>
2022-04-04 12:57:43 -04:00
Jeremy Cohen
3f37a43a8c Remove unneeded code in default snapshot materialization (#4993)
* Rm unneeded create_schema in snapshot mtlzn

* Add changelog entry
2022-04-04 17:25:53 +02:00
Gerda Shank
204d53516a Create a dbt.tests.adapter release when releasing dbt and postgres (#4948)
* update black version for pre-commit
2022-03-29 19:38:33 -04:00
Jeremy Cohen
5071b00baa Custom names for generic tests (#4898)
* Support user-supplied name for generic tests

* Support dict-style generic test spec

* Add changelog entry

* Add TODO comment

* Rework raise_duplicate_resource_name

* Add functional tests

* Update comments, rm TODO

* PR feedback
2022-03-25 17:09:35 +01:00
Emily Rockman
81118d904a Convert source tests (#4935)
* convert 059 to new test framework

* remove replaced tests

* WIP, has pre-commit errors

* WIP, has pre-commit errors

* one failing test, most issued resolved

* fixed final test and cleaned up fixtures

* remove converted tests

* updated test to work on windows

* remove config version
2022-03-24 09:19:54 -05:00
Jeremy Cohen
69cdc4148e Cosmetic changelog/changie fixups (#4944)
* Reorder kinds in changie

* Reorder change categories for v1.1.0b1

* Update language for breaking change

* Contributors deserve an h3

* Make pre-commit happy? Update language

* Rm trailing whitespace
2022-03-24 12:17:55 +01:00
Chenyu Li
1c71bf414d remove capping version of typing extensions (#4934) 2022-03-23 14:08:26 -04:00
Chenyu Li
7cf57ae72d add compliation and cache tracking (#4912) 2022-03-23 14:05:50 -04:00
kadero
1b6f95fef4 Fix inconsistent timestamps snapshots (#4513) 2022-03-23 12:05:42 -05:00
github-actions[bot]
38940eeeea Bumping version to 1.1.0b1 (#4933)
* Bumping version to 1.1.0b1
2022-03-23 09:28:50 -05:00
Ian Knox
6c950bad7c updated bumpversion (#4932) 2022-03-22 15:02:52 -05:00
Joel Labes
5e681929ae Add space before justification periods (#4744)
* Update format.py

* Update CHANGELOG.md

* add change file

Co-authored-by: Gerda Shank <gerda@dbtlabs.com>
2022-03-22 15:18:38 -04:00
Matthew McKnight
ea5a9da71e update of macro for postgres/redshift use of unique_key as a list (#4858)
* pre-commit additions

* added changie changelog entry

* moving integration test over

* Pair programming

* removing ref to mapping as seems to be unnecessary check, unique_key tests pass locally for postgres

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
2022-03-22 10:24:21 -05:00
leahwicz
9c5ee59e19 Updating backport workflow to use forked action (#4920) 2022-03-22 09:10:30 -04:00
Emily Rockman
55b1d3a191 changie - convert changelogs to yaml files and make quality of life improvements (#4917)
* convert changelog to changie yaml files

* update contributor format and README instructions

* update action to rerun when labeled/unlabled

* remove synchronize from action

* remove md file replaced by the yaml

* add synchronize and comment of what's happening

* tweak formatting
2022-03-21 20:15:52 -05:00
Ian Knox
a968aa7725 added permissions settings for docker release workflow (#4903) 2022-03-18 10:40:05 -05:00
Gerda Shank
5e0a765917 Set up adapter testing framework for use by adapter test repos (#4846) 2022-03-17 18:01:09 -04:00
Ian Knox
0aeb9976f4 remove missing setup.py file (holdover from pip install dbt (#4896) 2022-03-17 16:52:02 -05:00
Nathaniel May
30a7da8112 [HOTFIX] update dbt-extractor dependency (#4890)
* use pep 0440 compatible release operator for dbt-extractor dependency. bump to 0.4.1.
2022-03-17 16:44:30 -04:00
Matthew McKnight
f6a9dae422 FEAT: new columns in snapshots for adapters w/o bools (#4871)
* FEAT: new columns in snapshots for adapters w/o bools

* trigger gha workflow

* using changie to make changelog

* updating to be on par with main

Co-authored-by: swanderz <swanson.anders@gmail.com>
2022-03-17 10:10:23 -05:00
Gerda Shank
62a7163334 Use cli_vars instead of context to create package and selector renderers (#4878) 2022-03-17 09:27:39 -04:00
Mila Page
e2f0467f5d Add bugged version tag value to finds. (#4816)
* Change property file version exception to reflect current name and offer clearer guidance in comments.
* Add example in case of noninteger version tag just to drive the point home to readers.
2022-03-16 14:59:48 -07:00
Mila Page
3e3ecb1c3f get_response type hint is AdapterResponse only. (#4869)
* get_response type hint is AdapterResponse only.
* Propagate changes to get_response return type to execute
2022-03-16 14:54:39 -07:00
Nathaniel May
27511d807f update test project (#4875) 2022-03-16 16:35:07 -04:00
Ian Knox
15077d087c python 3.10 support (#4866)
* python 3.10 support
2022-03-15 19:35:28 -05:00
Emily Rockman
5b01cc0c22 catch all requests exceptions to retry (#4865)
* catch all requests exceptions to retry

* add changelog
2022-03-15 11:57:07 -05:00
Chenyu Li
d1bcff865d pytest conversion test_selection, schema_tests, fail_fast, permission (#4826) 2022-03-15 11:12:30 -04:00
Emily Rockman
0fce63665c Small changie fixes (#4857)
* fix broken links, update GHA to not repost comment

* tweak GHA

* convert GHA used

* consolidate GHA

* fix PR numbers and pull comment as var

* fix name of workflow step

* changie merge to fix link at top of changelog

* add changelog yaml
2022-03-11 14:54:33 -06:00
Emily Rockman
1183e85eb4 Er/ct 303 004 simple snapshot (#4838)
* convert single test in 004

* WIP

* incremental conversion

* WIP test not running

* WIP

* convert test_missing_strategy, cross_schema_snapshot

* comment

* converting to class based test

* clean up

* WIP

* converted 2 more tests

* convert hard delete test

* fixing inconsistencies, adding comments

* more conversion

* implementing class scope changes

* clean up unsed code

* remove old test, get all new ones running

* fix typos

* append file names with snapshot to reduce collision

* moved all fixtures into test files

* stop using tests as fixtures
2022-03-11 14:52:54 -06:00
dependabot[bot]
3b86243f04 Update typing-extensions requirement from <3.11,>=3.7.4 to >=3.7.4,<4.2 in /core (#4719)
* Update typing-extensions requirement in /core

Updates the requirements on [typing-extensions](https://github.com/python/typing) to permit the latest version.
- [Release notes](https://github.com/python/typing/releases)
- [Changelog](https://github.com/python/typing/blob/master/typing_extensions/CHANGELOG)
- [Commits](https://github.com/python/typing/compare/3.7.4...4.1.0)

---
updated-dependencies:
- dependency-name: typing-extensions
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Empty-Commit

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: ChenyuLi <chenyu.li@dbtlabs.com>
2022-03-10 15:42:20 -05:00
willbowditch
c251dae75e [CT-271] [Feature] not_null test selects column instead of * (#4777)
* Only select target column for not_null test

* If storing failures include all columns in the select, if not, only select the column being tested

It's desirable for this test to include the full row output when using --store-failures. If the query result stored in the database contained just the null values of the null column, it can't do much to contextualize why those rows are null.

* Update changelog

* chore: update changelog using changie

* Revert "Update changelog"

This reverts commit 281d805959.
2022-03-09 21:31:15 -05:00
Emily Rockman
ecfd77f1ca Small updates to clarify change destinations (#4841)
* update to reflect this branch is for the 1.1 release

* update to use next

* remove next logic

* add yaml changes also marked for unreleased 1.0.4
2022-03-08 13:18:24 -06:00
Emily Rockman
9a0abc1bfc Automate changelog (#4743)
* initial setup to use changie

* added `dbt-core` to version line

* fix formatting

* rename to be more accurate

* remove extra file

* add stug for contributing section

* updated docs for contributing and changelog

* first pass at changelog check

* Fix workflow name

* comment on handling failure

* add automatic contributors section via footer

* removed unused initialization

* add script to automate entire changelog creation and handle prereleases

* stub out README

* add changelog entry!

* no longer need to add contributors ourselves

* fixed formatted and excluded core team

* fix typo and collapse if statement

* updated to reflect automatic pre-release handling

Removed custom script in favor of built in pre-release functionality in new version of changie.

* update contributing doc

* pass at GHA

* fix path

* all changed files

* more GHA work

* continued GHA work

* try another approach

* testing

* adding comment via GHA

* added uses for GHA

* more debugging

* fixed formatting

* another comment attempt

* remove read permission

* add label check

* fix quotes

* checking label logic

* test forcing failure

* remove extra script tag

* removed logic for having changelog

* Revert "removed logic for having changelog"

This reverts commit 490bda8256.

* remove unused workflow section

* update header and readme

* update with current version of changelog

* add step failure for missing changelog file

* fix typos and formatting

* small tweaks per feedback

* Update so changelog end up onlywith current version, not past

* update changelog to recent contents

* added the rest of our releases to previous release list

* clarifying the readme

* updated to reflect current changelog state

* updated so only 1.1 changes are on main
2022-03-07 20:12:33 -06:00
Gerda Shank
490d68e076 Switch to using class scope fixtures (#4835)
* Switch to using class scope fixtures

* Reorganize some graph selection tests because of ci errors
2022-03-07 14:38:36 -05:00
Stu Kilgore
c45147fe6d Fix macro modified from previous state (#4820)
* Fix macro modified from previous state

Previously, if the first node selected by state:modified had multiple
dependencies, the first of which had not been changed, the rest of the
macro dependencies of the node would not be checked for changes. This
commit fixes this behavior, so the remainder of the macro dependencies
of the node will be checked as well.
2022-03-07 08:23:59 -06:00
Gerda Shank
bc3468e649 Convert tests in dbt-adapter-tests to use new pytest framework (#4815)
* Convert tests in dbt-adapter-tests to use new pytest framework

* Filter out ResourceWarning for log file

* Move run_sql to dbt.tests.util, fix check_cols definition

* Convert jaffle_shop fixture and test to use classes

* Tweak run_sql methods, rename some adapter file pieces, add comment
to dbt.tests.adapter.

* Add some more comments
2022-03-03 16:53:41 -05:00
Kyle Wigley
8fff6729a2 simplify and cleanup gha workflow (#4803) 2022-03-02 10:21:39 -05:00
varun-dc
08f50acb9e Fix stdout piped colored output on MacOS and Linux (#4792)
* Fix stdout pipe output coloring

* Update CHANGELOG.md

Co-authored-by: Chenyu Li <chenyulee777@gmail.com>

Co-authored-by: Chenyu Li <chenyulee777@gmail.com>
2022-03-01 17:23:51 -05:00
Chenyu Li
436a5f5cd4 add coverage (#4791) 2022-02-28 09:17:33 -05:00
Emily Rockman
aca710048f ct-237 test conversion 002_varchar_widening_tests (#4795)
* convert 002 integration test

* remove original test

* moved varchar test under basic folder
2022-02-25 14:25:22 -06:00
Emily Rockman
673ad50e21 updated index file to fix DAG errors for operations & work around null columns (#4763)
* updated index file to fix DAG errors for operations

* update index file to reflect dbt-docs fixes

* add changelog
2022-02-25 13:02:26 -06:00
Chenyu Li
8ee86a61a0 rewrite graph selection (#4783)
* rewrite graph selection
2022-02-25 12:09:11 -05:00
Gerda Shank
0dda0a90cf Fix errors on Windows tests in new tests/functional (#4767)
* [#4781] Convert reads and writes in project fixture to text/utf-8 encoding

* Switch to using write_file and read_file functions

* Add comment
2022-02-25 11:13:15 -05:00
Gerda Shank
220d8b888c Fix "dbt found two resources" error with multiple snapshot blocks in one file (#4773)
* Fix handling of multiple snapshot blocks in partial parsing

* Update tests for partial parsing snapshots
2022-02-25 10:54:07 -05:00
dependabot[bot]
42d5812577 Bump black from 21.12b0 to 22.1.0 (#4718)
Bumps [black](https://github.com/psf/black) from 21.12b0 to 22.1.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/commits/22.1.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-24 13:28:23 -05:00
Ian Knox
dea4f5f8ff update flake8 to remove line length req (#4779) 2022-02-24 11:22:25 -06:00
Dmytro Kazanzhy
8f50eee330 Fixed misspellings, typos, and duplicated words (#4545) 2022-02-22 18:05:43 -05:00
Gerda Shank
8fd8dfcf74 Initial pass at switching integration tests to pytest (#4691)
Author: Emily Rockman <emily.rockman@dbtlabs.com>
    route logs to dbt-core/logs instead of each test folder (#4711)

 * Initial pass at switching integration tests to pytest

* Reorganize dbt.tests.tables. Cleanup adapter handling

* Move run_sql to TestProjInfo and TableComparison.
Add comments, cleanup adapter schema setup

* Tweak unique_schema name generation

* Update CHANGELOG.md
2022-02-22 15:34:14 -05:00
Hein Bekker
10b27b9633 Deduplicate postgres relations (#3058) (#4521)
* Deduplicate postgres relations (#3058)

* Add changelog entry for #3058, #4521
2022-02-21 16:48:15 -06:00
Gerda Shank
5808ee6dd7 Fix bug accessing target in deps and clean commands (#4758)
* Create DictDefaultNone for to_target_dict in deps and clean commands

* Update test case to handle

* update CHANGELOG.md

* Switch to DictDefaultEmptyStr for to_target_dict
2022-02-21 13:26:29 -05:00
3644 changed files with 135182 additions and 75953 deletions

View File

@@ -1,13 +1,19 @@
[bumpversion]
current_version = 1.0.1
parse = (?P<major>\d+)
\.(?P<minor>\d+)
\.(?P<patch>\d+)
((?P<prekind>a|b|rc)
(?P<pre>\d+) # pre-release version num
current_version = 1.5.11
parse = (?P<major>[\d]+) # major version number
\.(?P<minor>[\d]+) # minor version number
\.(?P<patch>[\d]+) # patch version number
(?P<prerelease> # optional pre-release - ex: a1, b2, rc25
(?P<prekind>a|b|rc) # pre-release type
(?P<num>[\d]+) # pre-release version number
)?
( # optional nightly release indicator
\.(?P<nightly>dev[0-9]+) # ex: .dev02142023
)? # expected matches: `1.15.0`, `1.5.0a11`, `1.5.0a1.dev123`, `1.5.0.dev123457`, expected failures: `1`, `1.5`, `1.5.2-a1`, `text1.5.0`
serialize =
{major}.{minor}.{patch}{prekind}{pre}
{major}.{minor}.{patch}{prekind}{num}.{nightly}
{major}.{minor}.{patch}.{nightly}
{major}.{minor}.{patch}{prekind}{num}
{major}.{minor}.{patch}
commit = False
tag = False
@@ -21,19 +27,21 @@ values =
rc
final
[bumpversion:part:pre]
[bumpversion:part:num]
first_value = 1
[bumpversion:file:setup.py]
[bumpversion:part:nightly]
[bumpversion:file:core/setup.py]
[bumpversion:file:core/dbt/version.py]
[bumpversion:file:core/scripts/create_adapter_plugins.py]
[bumpversion:file:plugins/postgres/setup.py]
[bumpversion:file:plugins/postgres/dbt/adapters/postgres/__version__.py]
[bumpversion:file:docker/Dockerfile]
[bumpversion:file:tests/adapter/setup.py]
[bumpversion:file:tests/adapter/dbt/tests/adapter/__version__.py]

21
.changes/0.0.0.md Normal file
View File

@@ -0,0 +1,21 @@
## Previous Releases
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.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.0](https://github.com/dbt-labs/dbt-core/blob/1.0.latest/CHANGELOG.md)
* [0.21](https://github.com/dbt-labs/dbt-core/blob/0.21.latest/CHANGELOG.md)
* [0.20](https://github.com/dbt-labs/dbt-core/blob/0.20.latest/CHANGELOG.md)
* [0.19](https://github.com/dbt-labs/dbt-core/blob/0.19.latest/CHANGELOG.md)
* [0.18](https://github.com/dbt-labs/dbt-core/blob/0.18.latest/CHANGELOG.md)
* [0.17](https://github.com/dbt-labs/dbt-core/blob/0.17.latest/CHANGELOG.md)
* [0.16](https://github.com/dbt-labs/dbt-core/blob/0.16.latest/CHANGELOG.md)
* [0.15](https://github.com/dbt-labs/dbt-core/blob/0.15.latest/CHANGELOG.md)
* [0.14](https://github.com/dbt-labs/dbt-core/blob/0.14.latest/CHANGELOG.md)
* [0.13](https://github.com/dbt-labs/dbt-core/blob/0.13.latest/CHANGELOG.md)
* [0.12](https://github.com/dbt-labs/dbt-core/blob/0.12.latest/CHANGELOG.md)
* [0.11 and earlier](https://github.com/dbt-labs/dbt-core/blob/0.11.latest/CHANGELOG.md)

189
.changes/1.5.0.md Normal file
View File

@@ -0,0 +1,189 @@
## dbt-core 1.5.0 - April 27, 2023
### Breaking Changes
- Allow `--select` and `--exclude` multiple times ([#7158](https://github.com/dbt-labs/dbt-core/issues/7158))
- Specifying "log-path" and "target-path" in "dbt_project.yml" is deprecated. This functionality will be removed in a future version of dbt-core. If you need to specify a custom path for logs or artifacts, please set via CLI flag or env var instead. ([#6882](https://github.com/dbt-labs/dbt-core/issues/6882))
- Remove exception functions marked as deprecated in 1.4 release ([#6578](https://github.com/dbt-labs/dbt-core/issues/6578))
### Features
- Data type constraints are now native to SQL table materializations. Enforce columns are specific data types and not null depending on database functionality. ([#6079](https://github.com/dbt-labs/dbt-core/issues/6079))
- Have dbt debug spit out structured json logs with flags enabled. ([#5353](https://github.com/dbt-labs/dbt-core/issues/5353))
- ✨ add unix-style wildcard selector method ([#6598](https://github.com/dbt-labs/dbt-core/issues/6598))
- add adapter_response to dbt test and freshness result ([#2964](https://github.com/dbt-labs/dbt-core/issues/2964))
- add support for DBT_PROJECT_DIR env var ([#6078](https://github.com/dbt-labs/dbt-core/issues/6078))
- Improve error message for packages missing `dbt_project.yml` ([#6663](https://github.com/dbt-labs/dbt-core/issues/6663))
- Make project version optional ([#6603](https://github.com/dbt-labs/dbt-core/issues/6603))
- Adjust makefile to have clearer instructions for CI env var changes. ([#6689](https://github.com/dbt-labs/dbt-core/issues/6689))
- Stand-alone Python module for PostgresColumn ([#6772](https://github.com/dbt-labs/dbt-core/issues/6772))
- Enable diff based partial parsing ([#6592](https://github.com/dbt-labs/dbt-core/issues/6592))
- Exposure owner requires one of name or email keys, and accepts additional arbitrary keys ([#6833](https://github.com/dbt-labs/dbt-core/issues/6833))
- Parse 'group' resource ([#6921](https://github.com/dbt-labs/dbt-core/issues/6921))
- parse 'group' config on groupable nodes ([#6823](https://github.com/dbt-labs/dbt-core/issues/6823))
- Implemented new log cli parameters for finer-grained control. ([#6639](https://github.com/dbt-labs/dbt-core/issues/6639))
- Add access attribute to parsed nodes ([#6824](https://github.com/dbt-labs/dbt-core/issues/6824))
- Enforce contracts on models materialized as tables, views, and incremental ([#6751](https://github.com/dbt-labs/dbt-core/issues/6751), [#7034](https://github.com/dbt-labs/dbt-core/issues/7034), [#6756](https://github.com/dbt-labs/dbt-core/issues/6756), [#7154](https://github.com/dbt-labs/dbt-core/issues/7154))
- Add ability to select by group resource ([#6825](https://github.com/dbt-labs/dbt-core/issues/6825))
- Disallow refing private model across groups ([#6826](https://github.com/dbt-labs/dbt-core/issues/6826))
- make version configs optional ([#7054](https://github.com/dbt-labs/dbt-core/issues/7054))
- [CT-1584] New top level commands: interactive compile ([#6358](https://github.com/dbt-labs/dbt-core/issues/6358))
- Make model contracts agnostic to ordering ([#6975](https://github.com/dbt-labs/dbt-core/issues/6975), [#7064](https://github.com/dbt-labs/dbt-core/issues/7064))
- Unified constraints and check_constraints properties for columns and models ([#7066](https://github.com/dbt-labs/dbt-core/issues/7066))
- Switch from betterproto to google protobuf and enable more flexible meta dictionary in logs ([#6832](https://github.com/dbt-labs/dbt-core/issues/6832))
- Ignore duplicate edges in subgraph to speed up dbt build ([#7191](https://github.com/dbt-labs/dbt-core/issues/7191))
- Support setting of callbacks for programmatic uses of `dbtRunner` ([#6763](https://github.com/dbt-labs/dbt-core/issues/6763))
- Detect breaking changes to contracts in state:modified check ([#6869](https://github.com/dbt-labs/dbt-core/issues/6869))
- New command: dbt show ([#7207](https://github.com/dbt-labs/dbt-core/issues/7207), [#7179](https://github.com/dbt-labs/dbt-core/issues/7179), [#6359](https://github.com/dbt-labs/dbt-core/issues/6359))
- Added prettier printing to ContractError class ([#7209](https://github.com/dbt-labs/dbt-core/issues/7209))
- Add support for model-level constraints ([#6754](https://github.com/dbt-labs/dbt-core/issues/6754))
- model versions ([##7263](https://github.com/dbt-labs/dbt-core/issues/#7263))
- Add relation info (database, schema, alias) to node_info dictionary in structured logging ([#6724](https://github.com/dbt-labs/dbt-core/issues/6724))
- Add --no-populate-cache to optionally skip relation cache population ([#1751](https://github.com/dbt-labs/dbt-core/issues/1751))
- select resources by patch path ([#7315](https://github.com/dbt-labs/dbt-core/issues/7315))
- Add version selector method ([#7199](https://github.com/dbt-labs/dbt-core/issues/7199))
### Fixes
- Remove trailing slashes from source paths (#6102) ([#6102](https://github.com/dbt-labs/dbt-core/issues/6102))
- add merge_exclude_columns adapter tests ([#6699](https://github.com/dbt-labs/dbt-core/issues/6699))
- Include adapter_response in NodeFinished run_result log event ([#6703](https://github.com/dbt-labs/dbt-core/issues/6703))
- Sort cli vars before hashing for partial parsing ([#6710](https://github.com/dbt-labs/dbt-core/issues/6710))
- [Regression] exposure_content referenced incorrectly ([#6738](https://github.com/dbt-labs/dbt-core/issues/6738))
- Snapshot strategies: add a newline for subquery ([#6781](https://github.com/dbt-labs/dbt-core/issues/6781))
- Remove pin on packaging and stop using it for prerelease comparisons ([#6834](https://github.com/dbt-labs/dbt-core/issues/6834))
- Readd depends_on.macros to SeedNode, to support seeds with hooks calling macros ([#6806](https://github.com/dbt-labs/dbt-core/issues/6806))
- Fix regression of --quiet cli parameter behavior ([#6749](https://github.com/dbt-labs/dbt-core/issues/6749))
- Add double type to list of float column types for the column class ([#6876](https://github.com/dbt-labs/dbt-core/issues/6876))
- Ensure results from hooks contain nodes when processing them ([#6796](https://github.com/dbt-labs/dbt-core/issues/6796))
- Always flush stdout after logging ([#6901](https://github.com/dbt-labs/dbt-core/issues/6901))
- Reapply logging fixes which were accidentally reverted ([#6936](https://github.com/dbt-labs/dbt-core/issues/6936))
- Set relation_name in test nodes at compile time ([#6930](https://github.com/dbt-labs/dbt-core/issues/6930))
- Readd initialization events, --log-cache-events in new CLI ([#6933](https://github.com/dbt-labs/dbt-core/issues/6933))
- Fix previous state tests and disabled exposures, metrics ([#6752](https://github.com/dbt-labs/dbt-core/issues/6752), [#6753](https://github.com/dbt-labs/dbt-core/issues/6753))
- Make use of hashlib.md5() FIPS compliant ([#6900](https://github.com/dbt-labs/dbt-core/issues/6900))
- add timeout for dbt --version command ([#6992](https://github.com/dbt-labs/dbt-core/issues/6992))
- Fix compilation logic for ephemeral nodes ([#6885](https://github.com/dbt-labs/dbt-core/issues/6885))
- Fix semver comparison logic by ensuring numeric values ([#7039](https://github.com/dbt-labs/dbt-core/issues/7039))
- add pytz dependency ([#7077](https://github.com/dbt-labs/dbt-core/issues/7077))
- allow adapters to change model name resolution in py models ([#7114](https://github.com/dbt-labs/dbt-core/issues/7114))
- Add exception handling in postflight decorator to address exit codes ([#7010](https://github.com/dbt-labs/dbt-core/issues/7010))
- Recreates missing tracking events ([#6097](https://github.com/dbt-labs/dbt-core/issues/6097), [#6098](https://github.com/dbt-labs/dbt-core/issues/6098))
- Fix partial parsing error due to not requiring "version" ([#7236](https://github.com/dbt-labs/dbt-core/issues/7236))
- Handle internal exceptions ([#7118](https://github.com/dbt-labs/dbt-core/issues/7118))
- Improved failed event serialization handling and associated tests ([#7113](https://github.com/dbt-labs/dbt-core/issues/7113), [#7108](https://github.com/dbt-labs/dbt-core/issues/7108), [#6568](https://github.com/dbt-labs/dbt-core/issues/6568))
- Fix handling of artifacts in read_and_check_versions ([#7252](https://github.com/dbt-labs/dbt-core/issues/7252))
- Stringify datetimes in logging for prettier messages ([#7255](https://github.com/dbt-labs/dbt-core/issues/7255))
- avoid dbtRunner default callbacks being shared across instances ([#7278](https://github.com/dbt-labs/dbt-core/issues/7278))
- Ensure same_contract is called for state:modified ([#7282](https://github.com/dbt-labs/dbt-core/issues/7282))
- Avoid revoking grants for views when `copy_grants=true` ([#7280](https://github.com/dbt-labs/dbt-core/issues/7280))
- Duplicated flags now throw errors instead of being overidden by parent-level flag ([#6913](https://github.com/dbt-labs/dbt-core/issues/6913))
- Ensure that invocation_id changes between programmatic invocations. ([#7197](https://github.com/dbt-labs/dbt-core/issues/7197))
- Adding a new column is not a breaking contract change ([#7332](https://github.com/dbt-labs/dbt-core/issues/7332))
- fix versioned model selection in subdirectories ([#7348](https://github.com/dbt-labs/dbt-core/issues/7348))
- safe version attribute access in _check_resource_uniqueness ([#7375](https://github.com/dbt-labs/dbt-core/issues/7375))
- Fix dbt command missing target-path param ([# 7411](https://github.com/dbt-labs/dbt-core/issues/ 7411))
- Fix v0 ref resolution ([#7408](https://github.com/dbt-labs/dbt-core/issues/7408))
- fix groupable node partial parsing, raise DbtReferenceError at runtime for safety ([#7437](https://github.com/dbt-labs/dbt-core/issues/7437))
- Fix partial parsing of latest_version changes for downstream references ([#7369](https://github.com/dbt-labs/dbt-core/issues/7369))
### Docs
- Improve displayed message under "Arguments" section for argumentless macro ([dbt-docs/#358](https://github.com/dbt-labs/dbt-docs/issues/358))
- update link to installation instructions ([dbt-docs/#None](https://github.com/dbt-labs/dbt-docs/issues/None))
- Fix JSON path to overview docs ([dbt-docs/#366](https://github.com/dbt-labs/dbt-docs/issues/366))
- Searchable column descriptions ([dbt-docs/#140](https://github.com/dbt-labs/dbt-docs/issues/140), [dbt-docs/#322](https://github.com/dbt-labs/dbt-docs/issues/322), [dbt-docs/#369](https://github.com/dbt-labs/dbt-docs/issues/369))
- Add access property to model details ([dbt-docs/#381](https://github.com/dbt-labs/dbt-docs/issues/381))
- Display model owner by name and email ([dbt-docs/#377](https://github.com/dbt-labs/dbt-docs/issues/377))
- Add view of public models sorted by group to left navigation ([dbt-docs/#379](https://github.com/dbt-labs/dbt-docs/issues/379))
- Distiguish node "access" in the DAG with node borders & opacity. ([dbt-docs/#378](https://github.com/dbt-labs/dbt-docs/issues/378))
- Fix JSON path to package overview docs ([dbt-docs/#390](https://github.com/dbt-labs/dbt-docs/issues/390))
- Add selection by group to DAG ([dbt-docs/#380](https://github.com/dbt-labs/dbt-docs/issues/380))
- Add support for model versions ([dbt-docs/#406](https://github.com/dbt-labs/dbt-docs/issues/406))
### Under the Hood
- [CT-921] dbt compile works in click ([#5545](https://github.com/dbt-labs/dbt-core/issues/5545))
- Fix use of ConnectionReused logging event ([#6168](https://github.com/dbt-labs/dbt-core/issues/6168))
- Port docs tests to pytest ([#6573](https://github.com/dbt-labs/dbt-core/issues/6573))
- Update deprecated github action command ([#6153](https://github.com/dbt-labs/dbt-core/issues/6153))
- dbt snapshot works in click ([#5554](https://github.com/dbt-labs/dbt-core/issues/5554))
- dbt list working with click ([#5549](https://github.com/dbt-labs/dbt-core/issues/5549))
- Add dbt run-operation to click CLI ([#5552](https://github.com/dbt-labs/dbt-core/issues/5552))
- dbt build working with new click framework ([#5541](https://github.com/dbt-labs/dbt-core/issues/5541))
- dbt docs generate works with new click framework ([#5543](https://github.com/dbt-labs/dbt-core/issues/5543))
- Replaced the EmptyLine event with a more general Formatting event, and added a Note event. ([#6481](https://github.com/dbt-labs/dbt-core/issues/6481))
- Small optimization on manifest parsing benefitting large DAGs ([#6697](https://github.com/dbt-labs/dbt-core/issues/6697))
- Revised and simplified various structured logging events ([#6664](https://github.com/dbt-labs/dbt-core/issues/6664), [#6665](https://github.com/dbt-labs/dbt-core/issues/6665), [#6666](https://github.com/dbt-labs/dbt-core/issues/6666))
- dbt init works with click ([#5548](https://github.com/dbt-labs/dbt-core/issues/5548))
- [CT-920][CT-1900] Create Click CLI runner and use it to fix dbt docs commands ([#5544](https://github.com/dbt-labs/dbt-core/issues/5544), [#6722](https://github.com/dbt-labs/dbt-core/issues/6722))
- Migrate debug task to click ([#5546](https://github.com/dbt-labs/dbt-core/issues/5546))
- Optimized GraphQueue to remove graph analysis bottleneck in large dags. ([#6759](https://github.com/dbt-labs/dbt-core/issues/6759))
- Implement --version for click cli ([#6757](https://github.com/dbt-labs/dbt-core/issues/6757))
- [CT-1841] Convert custom target test to Pytest ([#6638](https://github.com/dbt-labs/dbt-core/issues/6638))
- Remove BigQuery-specific btye abbreviations ([#6741](https://github.com/dbt-labs/dbt-core/issues/6741))
- warn_error/warn_error_options mutual exclusivity in click ([#6579](https://github.com/dbt-labs/dbt-core/issues/6579))
- Enables the new Click Cli on the commandline! 🚀 ([#6784](https://github.com/dbt-labs/dbt-core/issues/6784))
- Lazily call --version ([#6812](https://github.com/dbt-labs/dbt-core/issues/6812))
- Moving simple_seed to adapter zone to help adapter test conversions ([#CT-1959](https://github.com/dbt-labs/dbt-core/issues/CT-1959))
- flags.THREADS defaults to None ([#6887](https://github.com/dbt-labs/dbt-core/issues/6887))
- Fixing target type exposure error ([#6928](https://github.com/dbt-labs/dbt-core/issues/6928))
- Test binary serialization of logging events ([#6852](https://github.com/dbt-labs/dbt-core/issues/6852))
- Treat contract config as a python object ([#6748](https://github.com/dbt-labs/dbt-core/issues/6748), [#7184](https://github.com/dbt-labs/dbt-core/issues/7184))
- Add deprecation warning for DBT_NO_PRINT ([#6960](https://github.com/dbt-labs/dbt-core/issues/6960))
- Make output_keys click param multi-option instead of a string ([#6676](https://github.com/dbt-labs/dbt-core/issues/6676))
- Remove cli doc generation workflow ([#7088](https://github.com/dbt-labs/dbt-core/issues/7088))
- Move validation of group earlier ([#7087](https://github.com/dbt-labs/dbt-core/issues/7087))
- Deprecate additional environment variables ([#6903](https://github.com/dbt-labs/dbt-core/issues/6903))
- Add CommandCompleted event, and fire it upon completion of every command ([#6878](https://github.com/dbt-labs/dbt-core/issues/6878))
- Improves build times for common selections by improving subgraph calculation ([#7195](https://github.com/dbt-labs/dbt-core/issues/7195))
- Remove upper pin for hologram/jsonschema ([#6775](https://github.com/dbt-labs/dbt-core/issues/6775))
- Generalize constraint compatibility warnings ([#7067](https://github.com/dbt-labs/dbt-core/issues/7067))
- Add kwargs support to dbtRunner ([#7070](https://github.com/dbt-labs/dbt-core/issues/7070))
- Add unique_id to ShowNode and CompiledNode logging events ([#7305](https://github.com/dbt-labs/dbt-core/issues/7305))
- Prettify message for ListRelations event ([#7310](https://github.com/dbt-labs/dbt-core/issues/7310))
- `Parse` now returns manifest when invoked via dbtRunner ([#6547](https://github.com/dbt-labs/dbt-core/issues/6547))
- Track data about group, access, contract, version usage ([#7170](https://github.com/dbt-labs/dbt-core/issues/7170), [#7171](https://github.com/dbt-labs/dbt-core/issues/7171))
- Update docs link in ContractBreakingChangeError message ([#7366](https://github.com/dbt-labs/dbt-core/issues/7366))
- Update --help text for cache-related parameters ([#7381](https://github.com/dbt-labs/dbt-core/issues/7381))
- Small UX improvements to model versions: Support defining latest_version in unsuffixed file by default. Notify on unpinned ref when a prerelease version is available. ([#7443](https://github.com/dbt-labs/dbt-core/issues/7443))
### Dependencies
- Update pathspec requirement from <0.11,>=0.9 to >=0.9,<0.12 in /core ([#6737](https://github.com/dbt-labs/dbt-core/pull/6737))
- Bump ubuntu from 22.04 to 23.04 ([#6865](https://github.com/dbt-labs/dbt-core/pull/6865))
- Revert hoisting dbt.cli.main into the dbt.name namespace ([#](https://github.com/dbt-labs/dbt-core/pull/))
- Bump python from 3.11.1-slim-bullseye to 3.11.2-slim-bullseye in /docker ([#7196](https://github.com/dbt-labs/dbt-core/pull/7196))
- Bump black from 22.12.0 to 23.3.0 ([#7243](https://github.com/dbt-labs/dbt-core/pull/7243))
- Bump mashumaro[msgpack] from 3.3.1 to 3.6 ([#7294](https://github.com/dbt-labs/dbt-core/pull/7294))
### Dependency
- Bump mypy from 0.971 to 0.981 ([#4904](https://github.com/dbt-labs/dbt-core/issues/4904))
- Bump python from 3.10.7-slim-bullseye to 3.11.1-slim-bullseye in /docker ([#4904](https://github.com/dbt-labs/dbt-core/issues/4904))
- Bump black from 22.10.0 to 22.12.0 ([#4904](https://github.com/dbt-labs/dbt-core/issues/4904))
### Contributors
- [@@ttusing](https://github.com/@ttusing) ([#7195](https://github.com/dbt-labs/dbt-core/issues/7195))
- [@Goodkat](https://github.com/Goodkat) ([#6992](https://github.com/dbt-labs/dbt-core/issues/6992))
- [@MartinGuindon](https://github.com/MartinGuindon) ([#358](https://github.com/dbt-labs/dbt-core/issues/358))
- [@MatthieuBlais](https://github.com/MatthieuBlais) ([#7191](https://github.com/dbt-labs/dbt-core/issues/7191))
- [@RobbertDM](https://github.com/RobbertDM) ([#6781](https://github.com/dbt-labs/dbt-core/issues/6781))
- [@aezomz](https://github.com/aezomz) ([#2964](https://github.com/dbt-labs/dbt-core/issues/2964))
- [@benallard](https://github.com/benallard) ([#7294](https://github.com/dbt-labs/dbt-core/pull/7294))
- [@boxysean](https://github.com/boxysean) ([#6697](https://github.com/dbt-labs/dbt-core/issues/6697))
- [@callum-mcdata](https://github.com/callum-mcdata) ([#6928](https://github.com/dbt-labs/dbt-core/issues/6928))
- [@chamini2](https://github.com/chamini2) ([#7278](https://github.com/dbt-labs/dbt-core/issues/7278))
- [@dave-connors-3](https://github.com/dave-connors-3) ([#7054](https://github.com/dbt-labs/dbt-core/issues/7054), [#7315](https://github.com/dbt-labs/dbt-core/issues/7315), [#6699](https://github.com/dbt-labs/dbt-core/issues/6699))
- [@davidbloss](https://github.com/davidbloss) ([#6153](https://github.com/dbt-labs/dbt-core/issues/6153))
- [@halvorlu](https://github.com/halvorlu) ([#366](https://github.com/dbt-labs/dbt-core/issues/366))
- [@jmg-duarte](https://github.com/jmg-duarte) ([#6102](https://github.com/dbt-labs/dbt-core/issues/6102))
- [@kentkr](https://github.com/kentkr) ([#7209](https://github.com/dbt-labs/dbt-core/issues/7209))
- [@leo-schick](https://github.com/leo-schick) ([#6078](https://github.com/dbt-labs/dbt-core/issues/6078))
- [@nielspardon](https://github.com/nielspardon) ([#6900](https://github.com/dbt-labs/dbt-core/issues/6900))
- [@rlh1994](https://github.com/rlh1994) ([#6876](https://github.com/dbt-labs/dbt-core/issues/6876), [#390](https://github.com/dbt-labs/dbt-core/issues/390))
- [@ryancharris](https://github.com/ryancharris) ([#None](https://github.com/dbt-labs/dbt-core/issues/None))
- [@sdebruyn](https://github.com/sdebruyn) ([#7077](https://github.com/dbt-labs/dbt-core/issues/7077))
- [@seub](https://github.com/seub) ([#6603](https://github.com/dbt-labs/dbt-core/issues/6603))
- [@sungchun12](https://github.com/sungchun12) ([#6079](https://github.com/dbt-labs/dbt-core/issues/6079))
- [@z3z1ma](https://github.com/z3z1ma) ([#6598](https://github.com/dbt-labs/dbt-core/issues/6598))

23
.changes/1.5.1.md Normal file
View File

@@ -0,0 +1,23 @@
## dbt-core 1.5.1 - May 30, 2023
### Fixes
- fix typo in unpacking statically parsed ref ([#7364](https://github.com/dbt-labs/dbt-core/issues/7364))
- Fix inverted `--print/--no-print` flag ([#7517](https://github.com/dbt-labs/dbt-core/issues/7517))
- Back-compat for previous return type of 'collect_freshness' macro ([#7489](https://github.com/dbt-labs/dbt-core/issues/7489))
- print model version in dbt show if specified ([#7407](https://github.com/dbt-labs/dbt-core/issues/7407))
- Allow missing `profiles.yml` for `dbt deps` and `dbt init` ([#7511](https://github.com/dbt-labs/dbt-core/issues/7511))
- Do not rewrite manifest.json during 'docs serve' command ([#7553](https://github.com/dbt-labs/dbt-core/issues/7553))
- Pin protobuf to greater than 4.0.0 ([#7565](https://github.com/dbt-labs/dbt-core/issues/7565))
- Throw error for duplicated versioned and unversioned models ([#7487](https://github.com/dbt-labs/dbt-core/issues/7487))
- Fix: Relative project paths weren't working with deps ([#7491](https://github.com/dbt-labs/dbt-core/issues/7491))
- Fall back if rendering the password field fails. ([#7629](https://github.com/dbt-labs/dbt-core/issues/7629))
- Stringify flag paths for Jinja context ([#7495](https://github.com/dbt-labs/dbt-core/issues/7495))
### Under the Hood
- Remove legacy file logger code ([#NA](https://github.com/dbt-labs/dbt-core/issues/NA))
### Contributors
- [@iknox-fa](https://github.com/iknox-fa) ([#7491](https://github.com/dbt-labs/dbt-core/issues/7491), [#NA](https://github.com/dbt-labs/dbt-core/issues/NA))
- [@thomasgjerdekog](https://github.com/thomasgjerdekog) ([#7517](https://github.com/dbt-labs/dbt-core/issues/7517))

9
.changes/1.5.10.md Normal file
View File

@@ -0,0 +1,9 @@
## dbt-core 1.5.10 - February 28, 2024
### Under the Hood
- Restrict protobuf to major version 4. ([#9566](https://github.com/dbt-labs/dbt-core/issues/9566))
### Security
- Update Jinja2 to >= 3.1.3 to address CVE-2024-22195 ([#CVE-2024-22195](https://github.com/dbt-labs/dbt-core/pull/CVE-2024-22195))

5
.changes/1.5.11.md Normal file
View File

@@ -0,0 +1,5 @@
## dbt-core 1.5.11 - March 28, 2024
### Dependencies
- Restrict protobuf to 4.* versions ([#9566](https://github.com/dbt-labs/dbt-core/pull/9566))

26
.changes/1.5.2.md Normal file
View File

@@ -0,0 +1,26 @@
## dbt-core 1.5.2 - June 22, 2023
### Features
- add access selection syntax ([#7738](https://github.com/dbt-labs/dbt-core/issues/7738))
- Add AdapterRegistered event log message ([#7038](https://github.com/dbt-labs/dbt-core/issues/7038))
### Fixes
- Add --target-path to dbt snapshot command. ([#7418](https://github.com/dbt-labs/dbt-core/issues/7418))
- Constraint rendering fixes: wrap check expression in parentheses, foreign key 'references', support expression in all constraint types ([#7417](https://github.com/dbt-labs/dbt-core/issues/7417), [#7480](https://github.com/dbt-labs/dbt-core/issues/7480), [#7416](https://github.com/dbt-labs/dbt-core/issues/7416))
- Fix warning messages for deprecated dbt_project.yml configs ([#7424](https://github.com/dbt-labs/dbt-core/issues/7424))
- Respect column 'quote' config in model contracts ([#7370](https://github.com/dbt-labs/dbt-core/issues/7370))
- Improve warnings for constraints and materialization types ([#7335](https://github.com/dbt-labs/dbt-core/issues/7335))
- Incorrect paths used for "target" and "state" directories ([#7465](https://github.com/dbt-labs/dbt-core/issues/7465))
- Using version 0 works when resolving single model ([#7372](https://github.com/dbt-labs/dbt-core/issues/7372))
- Fix empty --warn-error-options error message ([#7730](https://github.com/dbt-labs/dbt-core/issues/7730))
- send sql header on contract enforcement ([#7714](https://github.com/dbt-labs/dbt-core/issues/7714))
- Fix path selector when using project-dir ([#7819](https://github.com/dbt-labs/dbt-core/issues/7819))
- Allow dbt show --inline preview of private models ([#7837](https://github.com/dbt-labs/dbt-core/issues/7837))
- Updating this error message to point to the correct URL ([#7789](https://github.com/dbt-labs/dbt-core/issues/7789))
### Contributors
- [@dave-connors-3](https://github.com/dave-connors-3) ([#7738](https://github.com/dbt-labs/dbt-core/issues/7738))
- [@dwreeves](https://github.com/dwreeves) ([#7418](https://github.com/dbt-labs/dbt-core/issues/7418))
- [@mirnawong1](https://github.com/mirnawong1) ([#7789](https://github.com/dbt-labs/dbt-core/issues/7789))

18
.changes/1.5.3.md Normal file
View File

@@ -0,0 +1,18 @@
## dbt-core 1.5.3 - July 17, 2023
### Fixes
- Add --target-path to more CLI subcommands ([#7646](https://github.com/dbt-labs/dbt-core/issues/7646))
- Remove limitation on use of sqlparse 0.4.4 ([#7515](https://github.com/dbt-labs/dbt-core/issues/7515))
- Move project_root contextvar into events.contextvars ([#7937](https://github.com/dbt-labs/dbt-core/issues/7937))
- Inline query emit proper error message ([#7940](https://github.com/dbt-labs/dbt-core/issues/7940))
- Allow on_schema_change = fail for contracted incremental models ([#7975](https://github.com/dbt-labs/dbt-core/issues/7975))
- Nicer error message if model with enforced contract is missing 'columns' specification ([#7943](https://github.com/dbt-labs/dbt-core/issues/7943))
- Detect breaking contract changes to versioned models ([#8030](https://github.com/dbt-labs/dbt-core/issues/8030))
### Dependencies
- Pin click>=7.0,<8.1.4 ([#8050](https://github.com/dbt-labs/dbt-core/pull/8050))
### Contributors
- [@dwreeves](https://github.com/dwreeves) ([#7646](https://github.com/dbt-labs/dbt-core/issues/7646))

10
.changes/1.5.4.md Normal file
View File

@@ -0,0 +1,10 @@
## dbt-core 1.5.4 - July 28, 2023
### Fixes
- Ensure `warn_error_options` get serialized in `invocation_args_dict` ([#7694](https://github.com/dbt-labs/dbt-core/issues/7694))
- Improve handling of CTE injection with ephemeral models ([#8213](https://github.com/dbt-labs/dbt-core/issues/8213))
### Under the Hood
- Refactor flaky test pp_versioned_models ([#7781](https://github.com/dbt-labs/dbt-core/issues/7781))

16
.changes/1.5.5.md Normal file
View File

@@ -0,0 +1,16 @@
## dbt-core 1.5.5 - August 17, 2023
### Fixes
- Copy target_schema from config into snapshot node ([#6745](https://github.com/dbt-labs/dbt-core/issues/6745))
- Add status to Parse Inline Error ([#8173](https://github.com/dbt-labs/dbt-core/issues/8173))
- Fix using list command with path selector and project-dir ([#8385](https://github.com/dbt-labs/dbt-core/issues/8385))
### Under the Hood
- A way to control maxBytes for a single dbt.log file ([#8199](https://github.com/dbt-labs/dbt-core/issues/8199))
### Dependencies
- Update pin for click<9 ([#8232](https://github.com/dbt-labs/dbt-core/pull/8232))
- Add upper bound to sqlparse pin of <0.5 ([#8236](https://github.com/dbt-labs/dbt-core/pull/8236))

5
.changes/1.5.6.md Normal file
View File

@@ -0,0 +1,5 @@
## dbt-core 1.5.6 - August 21, 2023
### Under the Hood
- Use python version 3.10.7 in Docker image. ([#8444](https://github.com/dbt-labs/dbt-core/issues/8444))

12
.changes/1.5.7.md Normal file
View File

@@ -0,0 +1,12 @@
## dbt-core 1.5.7 - September 28, 2023
### Features
- Accept a `dbt-cloud` config in dbt_project.yml ([#8438](https://github.com/dbt-labs/dbt-core/issues/8438))
### Fixes
- Fix snapshot success message ([#7583](https://github.com/dbt-labs/dbt-core/issues/7583))
- update dbt show to include limit in DWH query ([#8496,](https://github.com/dbt-labs/dbt-core/issues/8496,), [#8417](https://github.com/dbt-labs/dbt-core/issues/8417))
- Support quoted parameter list for MultiOption CLI options. ([#8598](https://github.com/dbt-labs/dbt-core/issues/8598))
- avoid double-rendering sql_header in dbt show ([#8739](https://github.com/dbt-labs/dbt-core/issues/8739))

9
.changes/1.5.8.md Normal file
View File

@@ -0,0 +1,9 @@
## dbt-core 1.5.8 - October 11, 2023
### Fixes
- Support global flags passed in after subcommands ([#6497](https://github.com/dbt-labs/dbt-core/issues/6497))
- Foreign key constraint on incremental model results in Database Error ([#8022](https://github.com/dbt-labs/dbt-core/issues/8022))
- Support docs blocks on versioned model column descriptions ([#8540](https://github.com/dbt-labs/dbt-core/issues/8540))
- Enable seeds to be handled from stored manifest data ([#6875](https://github.com/dbt-labs/dbt-core/issues/6875))
- Group updates on unmodified nodes are handled gracefully for state:modified ([#8371](https://github.com/dbt-labs/dbt-core/issues/8371))

5
.changes/1.5.9.md Normal file
View File

@@ -0,0 +1,5 @@
## dbt-core 1.5.9 - October 31, 2023
### Fixes
- Add back contract enforcement for temporary tables on postgres ([#8857](https://github.com/dbt-labs/dbt-core/issues/8857))

53
.changes/README.md Normal file
View File

@@ -0,0 +1,53 @@
# CHANGELOG Automation
We use [changie](https://changie.dev/) to automate `CHANGELOG` generation. For installation and format/command specifics, see the documentation.
### Quick Tour
- All new change entries get generated under `/.changes/unreleased` as a yaml file
- `header.tpl.md` contains the contents of the entire CHANGELOG file
- `0.0.0.md` contains the contents of the footer for the entire CHANGELOG file. changie looks to be in the process of supporting a footer file the same as it supports a header file. Switch to that when available. For now, the 0.0.0 in the file name forces it to the bottom of the changelog no matter what version we are releasing.
- `.changie.yaml` contains the fields in a change, the format of a single change, as well as the format of the Contributors section for each version.
### Workflow
#### Daily workflow
Almost every code change we make associated with an issue will require a `CHANGELOG` entry. After you have created the PR in GitHub, run `changie new` and follow the command prompts to generate a yaml file with your change details. This only needs to be done once per PR.
The `changie new` command will ensure correct file format and file name. There is a one to one mapping of issues to changes. Multiple issues cannot be lumped into a single entry. If you make a mistake, the yaml file may be directly modified and saved as long as the format is preserved.
Note: If your PR has been cleared by the Core Team as not needing a changelog entry, the `Skip Changelog` label may be put on the PR to bypass the GitHub action that blacks PRs from being merged when they are missing a `CHANGELOG` entry.
#### Prerelease Workflow
These commands batch up changes in `/.changes/unreleased` to be included in this prerelease and move those files to a directory named for the release version. The `--move-dir` will be created if it does not exist and is created in `/.changes`.
```
changie batch <version> --move-dir '<version>' --prerelease 'rc1'
changie merge
```
Example
```
changie batch 1.0.5 --move-dir '1.0.5' --prerelease 'rc1'
changie merge
```
#### Final Release Workflow
These commands batch up changes in `/.changes/unreleased` as well as `/.changes/<version>` to be included in this final release and delete all prereleases. This rolls all prereleases up into a single final release. All `yaml` files in `/unreleased` and `<version>` will be deleted at this point.
```
changie batch <version> --include '<version>' --remove-prereleases
changie merge
```
Example
```
changie batch 1.0.5 --include '1.0.5' --remove-prereleases
changie merge
```
### A Note on Manual Edits & Gotchas
- Changie generates markdown files in the `.changes` directory that are parsed together with the `changie merge` command. Every time `changie merge` is run, it regenerates the entire file. For this reason, any changes made directly to `CHANGELOG.md` will be overwritten on the next run of `changie merge`.
- If changes need to be made to the `CHANGELOG.md`, make the changes to the relevant `<version>.md` file located in the `/.changes` directory. You will then run `changie merge` to regenerate the `CHANGELOG.MD`.
- Do not run `changie batch` again on released versions. Our final release workflow deletes all of the yaml files associated with individual changes. If for some reason modifications to the `CHANGELOG.md` are required after we've generated the final release `CHANGELOG.md`, the modifications need to be done manually to the `<version>.md` file in the `/.changes` directory.
- changie can modify, create and delete files depending on the command you run. This is expected. Be sure to commit everything that has been modified and deleted.

6
.changes/header.tpl.md Executable file
View File

@@ -0,0 +1,6 @@
# dbt Core Changelog
- This file provides a full account of all changes to `dbt-core` and `dbt-postgres`
- Changes are listed under the (pre)release in which they first appear. Subsequent releases include changes from previous releases.
- "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)

View File

@@ -0,0 +1,6 @@
kind: Security
body: Bump sqlparse to >=0.5.0, <0.6.0 to address GHSA-2m57-hf25-phgg
time: 2024-04-17T14:13:16.896353-05:00
custom:
Author: emmoop
Issue: "9951"

140
.changie.yaml Normal file
View File

@@ -0,0 +1,140 @@
changesDir: .changes
unreleasedDir: unreleased
headerPath: header.tpl.md
versionHeaderPath: ""
changelogPath: CHANGELOG.md
versionExt: md
envPrefix: "CHANGIE_"
versionFormat: '## dbt-core {{.Version}} - {{.Time.Format "January 02, 2006"}}'
kindFormat: '### {{.Kind}}'
changeFormat: |-
{{- $IssueList := list }}
{{- $changes := splitList " " $.Custom.Issue }}
{{- range $issueNbr := $changes }}
{{- $changeLink := "[#nbr](https://github.com/dbt-labs/dbt-core/issues/nbr)" | replace "nbr" $issueNbr }}
{{- $IssueList = append $IssueList $changeLink }}
{{- end -}}
- {{.Body}} ({{ range $index, $element := $IssueList }}{{if $index}}, {{end}}{{$element}}{{end}})
kinds:
- label: Breaking Changes
- label: Features
- label: Fixes
- label: Docs
changeFormat: |-
{{- $IssueList := list }}
{{- $changes := splitList " " $.Custom.Issue }}
{{- range $issueNbr := $changes }}
{{- $changeLink := "[dbt-docs/#nbr](https://github.com/dbt-labs/dbt-docs/issues/nbr)" | replace "nbr" $issueNbr }}
{{- $IssueList = append $IssueList $changeLink }}
{{- end -}}
- {{.Body}} ({{ range $index, $element := $IssueList }}{{if $index}}, {{end}}{{$element}}{{end}})
- label: Under the Hood
- label: Dependencies
changeFormat: |-
{{- $PRList := list }}
{{- $changes := splitList " " $.Custom.PR }}
{{- range $pullrequest := $changes }}
{{- $changeLink := "[#nbr](https://github.com/dbt-labs/dbt-core/pull/nbr)" | replace "nbr" $pullrequest }}
{{- $PRList = append $PRList $changeLink }}
{{- end -}}
- {{.Body}} ({{ range $index, $element := $PRList }}{{if $index}}, {{end}}{{$element}}{{end}})
skipGlobalChoices: true
additionalChoices:
- key: Author
label: GitHub Username(s) (separated by a single space if multiple)
type: string
minLength: 3
- key: PR
label: GitHub Pull Request Number (separated by a single space if multiple)
type: string
minLength: 1
- label: Security
changeFormat: |-
{{- $PRList := list }}
{{- $changes := splitList " " $.Custom.PR }}
{{- range $pullrequest := $changes }}
{{- $changeLink := "[#nbr](https://github.com/dbt-labs/dbt-core/pull/nbr)" | replace "nbr" $pullrequest }}
{{- $PRList = append $PRList $changeLink }}
{{- end -}}
- {{.Body}} ({{ range $index, $element := $PRList }}{{if $index}}, {{end}}{{$element}}{{end}})
skipGlobalChoices: true
additionalChoices:
- key: Author
label: GitHub Username(s) (separated by a single space if multiple)
type: string
minLength: 3
- key: PR
label: GitHub Pull Request Number (separated by a single space if multiple)
type: string
minLength: 1
newlines:
afterChangelogHeader: 1
afterKind: 1
afterChangelogVersion: 1
beforeKind: 1
endOfVersion: 1
custom:
- key: Author
label: GitHub Username(s) (separated by a single space if multiple)
type: string
minLength: 3
- key: Issue
label: GitHub Issue Number (separated by a single space if multiple)
type: string
minLength: 1
footerFormat: |
{{- $contributorDict := dict }}
{{- /* ensure all names in this list are all lowercase for later matching purposes */}}
{{- $core_team := splitList " " .Env.CORE_TEAM }}
{{- /* ensure we always skip snyk and dependabot in addition to the core team */}}
{{- $maintainers := list "dependabot[bot]" "snyk-bot"}}
{{- range $team_member := $core_team }}
{{- $team_member_lower := lower $team_member }}
{{- $maintainers = append $maintainers $team_member_lower }}
{{- end }}
{{- range $change := .Changes }}
{{- $authorList := splitList " " $change.Custom.Author }}
{{- /* loop through all authors for a single changelog */}}
{{- range $author := $authorList }}
{{- $authorLower := lower $author }}
{{- /* we only want to include non-core team contributors */}}
{{- if not (has $authorLower $maintainers)}}
{{- $changeList := splitList " " $change.Custom.Author }}
{{- $IssueList := list }}
{{- $changeLink := $change.Kind }}
{{- if or (eq $change.Kind "Dependencies") (eq $change.Kind "Security") }}
{{- $changes := splitList " " $change.Custom.PR }}
{{- range $issueNbr := $changes }}
{{- $changeLink := "[#nbr](https://github.com/dbt-labs/dbt-core/pull/nbr)" | replace "nbr" $issueNbr }}
{{- $IssueList = append $IssueList $changeLink }}
{{- end -}}
{{- else }}
{{- $changes := splitList " " $change.Custom.Issue }}
{{- range $issueNbr := $changes }}
{{- $changeLink := "[#nbr](https://github.com/dbt-labs/dbt-core/issues/nbr)" | replace "nbr" $issueNbr }}
{{- $IssueList = append $IssueList $changeLink }}
{{- end -}}
{{- end }}
{{- /* check if this contributor has other changes associated with them already */}}
{{- if hasKey $contributorDict $author }}
{{- $contributionList := get $contributorDict $author }}
{{- $contributionList = concat $contributionList $IssueList }}
{{- $contributorDict := set $contributorDict $author $contributionList }}
{{- else }}
{{- $contributionList := $IssueList }}
{{- $contributorDict := set $contributorDict $author $contributionList }}
{{- end }}
{{- end}}
{{- end}}
{{- end }}
{{- /* no indentation here for formatting so the final markdown doesn't have unneeded indentations */}}
{{- if $contributorDict}}
### Contributors
{{- range $k,$v := $contributorDict }}
- [@{{$k}}](https://github.com/{{$k}}) ({{ range $index, $element := $v }}{{if $index}}, {{end}}{{$element}}{{end}})
{{- end }}
{{- end }}

View File

@@ -8,5 +8,5 @@ ignore =
W504
E203 # makes Flake8 work like black
E741
max-line-length = 99
exclude = test
E501 # long line checking is done in black
exclude = test/

2
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,2 @@
# Reformatting dbt-core via black, flake8, mypy, and assorted pre-commit hooks.
43e3fc22c4eae4d3d901faba05e33c40f1f1dc5a

6
.gitattributes vendored Normal file
View File

@@ -0,0 +1,6 @@
core/dbt/include/index.html binary
tests/functional/artifacts/data/state/*/manifest.json binary
core/dbt/docs/build/html/searchindex.js binary
core/dbt/docs/build/html/index.html binary
performance/runner/Cargo.lock binary
core/dbt/events/types_pb2.py binary

60
.github/CODEOWNERS vendored
View File

@@ -16,25 +16,57 @@
# Changes to GitHub configurations including Actions
/.github/ @leahwicz
### LANGUAGE
# Language core modules
/core/dbt/config/ @dbt-labs/core-language
/core/dbt/context/ @dbt-labs/core-language
/core/dbt/contracts/ @dbt-labs/core-language
/core/dbt/deps/ @dbt-labs/core-language
/core/dbt/parser/ @dbt-labs/core-language
/core/dbt/config/ @dbt-labs/core-language
/core/dbt/context/ @dbt-labs/core-language
/core/dbt/contracts/ @dbt-labs/core-language
/core/dbt/deps/ @dbt-labs/core-language
/core/dbt/events/ @dbt-labs/core-language # structured logging
/core/dbt/parser/ @dbt-labs/core-language
# Language misc files
/core/dbt/dataclass_schema.py @dbt-labs/core-language
/core/dbt/hooks.py @dbt-labs/core-language
/core/dbt/node_types.py @dbt-labs/core-language
/core/dbt/semver.py @dbt-labs/core-language
### EXECUTION
# Execution core modules
/core/dbt/events/ @dbt-labs/core-execution @dbt-labs/core-language # eventually remove language but they have knowledge here now
/core/dbt/graph/ @dbt-labs/core-execution
/core/dbt/task/ @dbt-labs/core-execution
/core/dbt/graph/ @dbt-labs/core-execution
/core/dbt/task/ @dbt-labs/core-execution
# Adapter interface, scaffold, Postgres plugin
/core/dbt/adapters @dbt-labs/core-adapters
/core/scripts/create_adapter_plugin.py @dbt-labs/core-adapters
/plugins/ @dbt-labs/core-adapters
# Execution misc files
/core/dbt/compilation.py @dbt-labs/core-execution
/core/dbt/flags.py @dbt-labs/core-execution
/core/dbt/lib.py @dbt-labs/core-execution
/core/dbt/main.py @dbt-labs/core-execution
/core/dbt/profiler.py @dbt-labs/core-execution
/core/dbt/selected_resources.py @dbt-labs/core-execution
/core/dbt/tracking.py @dbt-labs/core-execution
/core/dbt/version.py @dbt-labs/core-execution
# Global project: default macros, including generic tests + materializations
/core/dbt/include/global_project @dbt-labs/core-execution @dbt-labs/core-adapters
### ADAPTERS
# Adapter interface ("base" + "sql" adapter defaults, cache)
/core/dbt/adapters @dbt-labs/core-adapters
# Global project (default macros + materializations), starter project
/core/dbt/include @dbt-labs/core-adapters
# Postgres plugin
/plugins/ @dbt-labs/core-adapters
# Functional tests for adapter plugins
/tests/adapter @dbt-labs/core-adapters
### TESTS
# Overlapping ownership for vast majority of unit + functional tests
# Perf regression testing framework
# This excludes the test project files itself since those aren't specific

View File

@@ -9,23 +9,33 @@ body:
Thanks for taking the time to fill out this bug report!
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
label: Is this a new bug in dbt-core?
description: >
In other words, is this an error, flaw, failure or fault in our software?
If this is a bug that broke existing functionality that used to work, please open a regression issue.
If this is a bug in an adapter plugin, please open an issue in the adapter's repository.
If this is a bug experienced while using dbt Cloud, please report to [support](mailto:support@getdbt.com).
If this is a request for help or troubleshooting code in your own dbt project, please join our [dbt Community Slack](https://www.getdbt.com/community/join-the-community/) or open a [Discussion question](https://github.com/dbt-labs/docs.getdbt.com/discussions).
Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
- label: I believe this is a new bug in dbt-core
required: true
- label: I have searched the existing issues, and I could not find an existing issue for this bug
required: true
- type: textarea
attributes:
label: Current Behavior
description: A concise description of what you're experiencing.
validations:
required: false
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: false
required: true
- type: textarea
attributes:
label: Steps To Reproduce
@@ -36,7 +46,7 @@ body:
3. Run '...'
4. See error...
validations:
required: false
required: true
- type: textarea
id: logs
attributes:
@@ -52,8 +62,8 @@ body:
description: |
examples:
- **OS**: Ubuntu 20.04
- **Python**: 3.7.2 (`python --version`)
- **dbt**: 0.21.0 (`dbt --version`)
- **Python**: 3.9.12 (`python3 --version`)
- **dbt-core**: 1.1.1 (`dbt --version`)
value: |
- OS:
- Python:
@@ -64,13 +74,15 @@ body:
- type: dropdown
id: database
attributes:
label: What database are you using dbt with?
label: Which database adapter are you using with dbt?
description: If the bug is specific to the database or adapter, please open the issue in that adapter's repository instead
multiple: true
options:
- postgres
- redshift
- snowflake
- bigquery
- spark
- other (mention it in "Additional Context")
validations:
required: false

View File

@@ -1,4 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: Ask the community for help
url: https://github.com/dbt-labs/docs.getdbt.com/discussions
about: Need help troubleshooting? Check out our guide on how to ask
- name: Contact dbt Cloud support
url: mailto:support@getdbt.com
about: Are you using dbt Cloud? Contact our support team for help!
- name: Participate in Discussions
url: https://github.com/dbt-labs/dbt-core/discussions
about: Do you have a Big Idea for dbt? Read open discussions, or start a new one
- name: Create an issue for dbt-redshift
url: https://github.com/dbt-labs/dbt-redshift/issues/new/choose
about: Report a bug or request a feature for dbt-redshift
@@ -8,9 +18,6 @@ contact_links:
- name: Create an issue for dbt-snowflake
url: https://github.com/dbt-labs/dbt-snowflake/issues/new/choose
about: Report a bug or request a feature for dbt-snowflake
- name: Ask a question or get support
url: https://docs.getdbt.com/docs/guides/getting-help
about: Ask a question or request support
- name: Questions on Stack Overflow
url: https://stackoverflow.com/questions/tagged/dbt
about: Look at questions/answers at Stack Overflow
- name: Create an issue for dbt-spark
url: https://github.com/dbt-labs/dbt-spark/issues/new/choose
about: Report a bug or request a feature for dbt-spark

View File

@@ -1,22 +1,32 @@
name: ✨ Feature
description: Suggest an idea for dbt
description: Propose a straightforward extension of dbt functionality
title: "[Feature] <title>"
labels: ["enhancement", "triage"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this feature requests!
Thanks for taking the time to fill out this feature request!
- type: checkboxes
attributes:
label: Is there an existing feature request for this?
description: Please search to see if an issue already exists for the feature you would like.
label: Is this your first time submitting a feature request?
description: >
We want to make sure that features are distinct and discoverable,
so that other members of the community can find them and offer their thoughts.
Issues are the right place to request straightforward extensions of existing dbt functionality.
For "big ideas" about future capabilities of dbt, we ask that you open a
[discussion](https://github.com/dbt-labs/dbt-core/discussions) in the "Ideas" category instead.
options:
- label: I have searched the existing issues
- label: I have read the [expectations for open source contributors](https://docs.getdbt.com/docs/contributing/oss-expectations)
required: true
- label: I have searched the existing issues, and I could not find an existing issue for this feature
required: true
- label: I am requesting a straightforward extension of existing dbt functionality, rather than a Big Idea better suited to a discussion
required: true
- type: textarea
attributes:
label: Describe the Feature
label: Describe the feature
description: A clear and concise description of what you want to happen.
validations:
required: true

View File

@@ -0,0 +1,93 @@
name: ☣️ Regression
description: Report a regression you've observed in a newer version of dbt
title: "[Regression] <title>"
labels: ["bug", "regression", "triage"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this regression report!
- type: checkboxes
attributes:
label: Is this a regression in a recent version of dbt-core?
description: >
A regression is when documented functionality works as expected in an older version of dbt-core,
and no longer works after upgrading to a newer version of dbt-core
options:
- label: I believe this is a regression in dbt-core functionality
required: true
- label: I have searched the existing issues, and I could not find an existing issue for this regression
required: true
- type: textarea
attributes:
label: Current Behavior
description: A concise description of what you're experiencing.
validations:
required: true
- type: textarea
attributes:
label: Expected/Previous Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. In this environment...
2. With this config...
3. Run '...'
4. See error...
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: |
If applicable, log output to help explain your problem.
render: shell
validations:
required: false
- type: textarea
attributes:
label: Environment
description: |
examples:
- **OS**: Ubuntu 20.04
- **Python**: 3.9.12 (`python3 --version`)
- **dbt-core (working version)**: 1.1.1 (`dbt --version`)
- **dbt-core (regression version)**: 1.2.0 (`dbt --version`)
value: |
- OS:
- Python:
- dbt (working version):
- dbt (regression version):
render: markdown
validations:
required: true
- type: dropdown
id: database
attributes:
label: Which database adapter are you using with dbt?
description: If the regression is specific to the database or adapter, please open the issue in that adapter's repository instead
multiple: true
options:
- postgres
- redshift
- snowflake
- bigquery
- spark
- other (mention it in "Additional Context")
validations:
required: false
- type: textarea
attributes:
label: Additional Context
description: |
Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false

216
.github/_README.md vendored Normal file
View File

@@ -0,0 +1,216 @@
<!-- GitHub will publish this readme on the main repo page if the name is `README.md` so we've added the leading underscore to prevent this -->
<!-- Do not rename this file `README.md` -->
<!-- See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes -->
## What are GitHub Actions?
GitHub Actions are used for many different purposes. We use them to run tests in CI, validate PRs are in an expected state, and automate processes.
- [Overview of GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions)
- [What's a workflow?](https://docs.github.com/en/actions/using-workflows/about-workflows)
- [GitHub Actions guides](https://docs.github.com/en/actions/guides)
___
## Where do actions and workflows live
We try to maintain actions that are shared across repositories in a single place so that necesary changes can be made in a single place.
[dbt-labs/actions](https://github.com/dbt-labs/actions/) is the central repository of actions and workflows we use across repositories.
GitHub Actions also live locally within a repository. The workflows can be found at `.github/workflows` from the root of the repository. These should be specific to that code base.
Note: We are actively moving actions into the central Action repository so there is currently some duplication across repositories.
___
## Basics of Using Actions
### Viewing Output
- View the detailed action output for your PR in the **Checks** tab of the PR. This only shows the most recent run. You can also view high level **Checks** output at the bottom on the PR.
- View _all_ action output for a repository from the [**Actions**](https://github.com/dbt-labs/dbt-core/actions) tab. Workflow results last 1 year. Artifacts last 90 days, unless specified otherwise in individual workflows.
This view often shows what seem like duplicates of the same workflow. This occurs when files are renamed but the workflow name has not changed. These are in fact _not_ duplicates.
You can see the branch the workflow runs from in this view. It is listed in the table between the workflow name and the time/duration of the run. When blank, the workflow is running in the context of the `main` branch.
### How to view what workflow file is being referenced from a run
- When viewing the output of a specific workflow run, click the 3 dots at the top right of the display. There will be an option to `View workflow file`.
### How to manually run a workflow
- If a workflow has the `on: workflow_dispatch` trigger, it can be manually triggered
- From the [**Actions**](https://github.com/dbt-labs/dbt-core/actions) tab, find the workflow you want to run, select it and fill in any inputs requied. That's it!
### How to re-run jobs
- Some actions cannot be rerun in the GitHub UI. Namely the snyk checks and the cla check. Snyk checks are rerun by closing and reopening the PR. You can retrigger the cla check by commenting on the PR with `@cla-bot check`
___
## General Standards
### Permissions
- By default, workflows have read permissions in the repository for the contents scope only when no permissions are explicitly set.
- It is best practice to always define the permissions explicitly. This will allow actions to continue to work when the default permissions on the repository are changed. It also allows explicit grants of the least permissions possible.
- There are a lot of permissions available. [Read up on them](https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs) if you're unsure what to use.
```yaml
permissions:
contents: read
pull-requests: write
```
### 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?
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.
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.
### Triggers
You can configure your workflows to run when specific activity on GitHub happens, at a scheduled time, or when an event outside of GitHub occurs. Read more details in the [GitHub docs](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows).
These triggers are under the `on` key of the workflow and more than one can be listed.
```yaml
on:
push:
branches:
- "main"
- "*.latest"
- "releases/*"
pull_request:
# catch when the PR is opened with the label or when the label is added
types: [opened, labeled]
workflow_dispatch:
```
Some triggers of note that we use:
- `push` - Runs your workflow when you push a commit or tag.
- `pull_request` - Runs your workflow when activity on a pull request in the workflow's repository occurs. Takes in a list of activity types (opened, labeled, etc) if appropriate.
- `pull_request_target` - Same as `pull_request` but runs in the context of the PR target branch.
- `workflow_call` - used with reusable workflows. Triggered by another workflow calling it.
- `workflow_dispatch` - Gives the ability to manually trigger a workflow from the GitHub API, GitHub CLI, or GitHub browser interface.
### Basic Formatting
- Add a description of what your workflow does at the top in this format
```
# **what?**
# Describe what the action does.
# **why?**
# Why does this action exist?
# **when?**
# How/when will it be triggered?
```
- Leave blank lines between steps and jobs
```yaml
jobs:
dependency_changelog:
runs-on: ubuntu-latest
steps:
- name: Get File Name Timestamp
id: filename_time
uses: nanzm/get-time-action@v1.1
with:
format: 'YYYYMMDD-HHmmss'
- name: Get File Content Timestamp
id: file_content_time
uses: nanzm/get-time-action@v1.1
with:
format: 'YYYY-MM-DDTHH:mm:ss.000000-05:00'
- name: Generate Filepath
id: fp
run: |
FILEPATH=.changes/unreleased/Dependencies-${{ steps.filename_time.outputs.time }}.yaml
echo "FILEPATH=$FILEPATH" >> $GITHUB_OUTPUT
```
- 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.
When possible, generate variables at the top of your workflow in a single place to reference later. This is not always strictly possible since you may generate a value to be used later mid-workflow.
Be sure to use quotes around these logs so special characters are not interpreted.
```yaml
job1:
- name: "[DEBUG] Print Variables"
run: |
echo "all variables defined as inputs"
echo "The last commit sha in the release: ${{ inputs.sha }}"
echo "The release version number: ${{ inputs.version_number }}"
echo "The changelog_path: ${{ inputs.changelog_path }}"
echo "The build_script_path: ${{ inputs.build_script_path }}"
echo "The s3_bucket_name: ${{ inputs.s3_bucket_name }}"
echo "The package_test_command: ${{ inputs.package_test_command }}"
# collect all the variables that need to be used in subsequent jobs
- name: Set Variables
id: variables
run: |
echo "important_path='performance/runner/Cargo.toml'" >> $GITHUB_OUTPUT
echo "release_id=${{github.event.inputs.release_id}}" >> $GITHUB_OUTPUT
echo "open_prs=${{github.event.inputs.open_prs}}" >> $GITHUB_OUTPUT
job2:
needs: [job1]
- name: "[DEBUG] Print Variables"
run: |
echo "all variables defined in job1 > Set Variables > outputs"
echo "important_path: ${{ needs.job1.outputs.important_path }}"
echo "release_id: ${{ needs.job1.outputs.release_id }}"
echo "open_prs: ${{ needs.job1.outputs.open_prs }}"
```
- When it's not obvious what something does, add a comment!
___
## Tips
### Context
- The [GitHub CLI](https://cli.github.com/) is available in the default runners
- Actions run in your context. ie, using an action from the marketplace that uses the GITHUB_TOKEN uses the GITHUB_TOKEN generated by your workflow run.
### Actions from the Marketplace
- 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
- Pin actions _we don't control_ to tags.
### Connecting to AWS
- Authenticate with the aws managed workflow
```yaml
- name: Configure AWS credentials from Test account
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
```
- Then access with the aws command that comes installed on the action runner machines
```yaml
- name: Copy Artifacts from S3 via CLI
run: aws s3 cp ${{ env.s3_bucket }} . --recursive
```
### Testing
- Depending on what your action does, you may be able to use [`act`](https://github.com/nektos/act) to test the action locally. Some features of GitHub Actions do not work with `act`, among those are reusable workflows. If you can't use `act`, you'll have to push your changes up before being able to test. This can be slow.

View File

@@ -13,7 +13,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- name: Wrangle latest tag
id: is_latest
uses: ./.github/actions/latest-wrangler

View File

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

View File

@@ -15,7 +15,9 @@ resolves #
### Checklist
- [ ] I have read [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md) and understand what's expected of me
- [ ] I have signed the [CLA](https://docs.getdbt.com/docs/contributor-license-agreements)
- [ ] I have run this code in development and it appears to resolve the stated issue
- [ ] This PR includes tests, or tests are not required/relevant for this PR
- [ ] I have updated the `CHANGELOG.md` and added information about my change
- [ ] I have [opened an issue to add/update docs](https://github.com/dbt-labs/docs.getdbt.com/issues/new/choose), or docs changes are not required/relevant for this PR
- [ ] I have run `changie new` to [create a changelog entry](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md#adding-a-changelog-entry)

View File

@@ -1,95 +0,0 @@
module.exports = ({ context }) => {
const defaultPythonVersion = "3.8";
const supportedPythonVersions = ["3.7", "3.8", "3.9"];
const supportedAdapters = ["postgres"];
// if PR, generate matrix based on files changed and PR labels
if (context.eventName.includes("pull_request")) {
// `changes` is a list of adapter names that have related
// file changes in the PR
// ex: ['postgres', 'snowflake']
const changes = JSON.parse(process.env.CHANGES);
const labels = context.payload.pull_request.labels.map(({ name }) => name);
console.log("labels", labels);
console.log("changes", changes);
const testAllLabel = labels.includes("test all");
const include = [];
for (const adapter of supportedAdapters) {
if (
changes.includes(adapter) ||
testAllLabel ||
labels.includes(`test ${adapter}`)
) {
for (const pythonVersion of supportedPythonVersions) {
if (
pythonVersion === defaultPythonVersion ||
labels.includes(`test python${pythonVersion}`) ||
testAllLabel
) {
// always run tests on ubuntu by default
include.push({
os: "ubuntu-latest",
adapter,
"python-version": pythonVersion,
});
if (labels.includes("test windows") || testAllLabel) {
include.push({
os: "windows-latest",
adapter,
"python-version": pythonVersion,
});
}
if (labels.includes("test macos") || testAllLabel) {
include.push({
os: "macos-latest",
adapter,
"python-version": pythonVersion,
});
}
}
}
}
}
console.log("matrix", { include });
return {
include,
};
}
// if not PR, generate matrix of python version, adapter, and operating
// system to run integration tests on
const include = [];
// run for all adapters and python versions on ubuntu
for (const adapter of supportedAdapters) {
for (const pythonVersion of supportedPythonVersions) {
include.push({
os: 'ubuntu-latest',
adapter: adapter,
"python-version": pythonVersion,
});
}
}
// additionally include runs for all adapters, on macos and windows,
// but only for the default python version
for (const adapter of supportedAdapters) {
for (const operatingSystem of ["windows-latest", "macos-latest"]) {
include.push({
os: operatingSystem,
adapter: adapter,
"python-version": defaultPythonVersion,
});
}
}
console.log("matrix", { include });
return {
include,
};
};

View File

@@ -13,22 +13,28 @@
# This automates the backporting process
# **when?**
# Once a PR is "Squash and merge"'d and it has been correctly labeled
# according to the naming convention.
# Once a PR is "Squash and merge"'d, by adding a backport label, this is triggered
name: Backport
on:
pull_request:
types:
- closed
- labeled
permissions:
contents: write
pull-requests: write
jobs:
backport:
runs-on: ubuntu-18.04
name: Backport
runs-on: ubuntu-latest
# Only react to merged PRs for security reasons.
# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
if: >
github.event.pull_request.merged
&& contains(github.event.label.name, 'backport')
steps:
- name: Backport
uses: tibdex/backport@v1.1.1
- uses: tibdex/backport@v2.0.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

61
.github/workflows/bot-changelog.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
# **what?**
# When bots create a PR, this action will add a corresponding changie yaml file to that
# PR when a specific label is added.
#
# The file is created off a template:
#
# kind: <per action matrix>
# body: <PR title>
# time: <current timestamp>
# custom:
# Author: <PR User Login (generally the bot)>
# Issue: 4904
# PR: <PR number>
#
# **why?**
# Automate changelog generation for more visability with automated bot PRs.
#
# **when?**
# Once a PR is created, label should be added to PR before or after creation. You can also
# manually trigger this by adding the appropriate label at any time.
#
# **how to add another bot?**
# Add the label and changie kind to the include matrix. That's it!
#
name: Bot Changelog
on:
pull_request:
# catch when the PR is opened with the label or when the label is added
types: [labeled]
permissions:
contents: write
pull-requests: read
jobs:
generate_changelog:
strategy:
matrix:
include:
- label: "dependencies"
changie_kind: "Dependencies"
- label: "snyk"
changie_kind: "Security"
runs-on: ubuntu-latest
steps:
- name: Create and commit changelog on bot PR
if: ${{ contains(github.event.pull_request.labels.*.name, matrix.label) }}
id: bot_changelog
uses: emmyoop/changie_bot@v1.0.1
with:
GITHUB_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}
commit_author_name: "Github Build Bot"
commit_author_email: "<buildbot@fishtownanalytics.com>"
commit_message: "Add automated changelog yaml from template for bot PR"
changie_kind: ${{ matrix.changie_kind }}
label: ${{ matrix.label }}
custom_changelog_string: "custom:\n Author: ${{ github.event.pull_request.user.login }}\n PR: ${{ github.event.pull_request.number }}"

View File

@@ -0,0 +1,40 @@
# **what?**
# Checks that a file has been committed under the /.changes directory
# as a new CHANGELOG entry. Cannot check for a specific filename as
# it is dynamically generated by change type and timestamp.
# This workflow should not require any secrets since it runs for PRs
# from forked repos.
# By default, secrets are not passed to workflows running from
# a forked repo.
# **why?**
# Ensure code change gets reflected in the CHANGELOG.
# **when?**
# This will run for all PRs going into main and *.latest. It will
# run when they are opened, reopened, when any label is added or removed
# and when new code is pushed to the branch. The action will then get
# skipped if the 'Skip Changelog' label is present is any of the labels.
name: Check Changelog Entry
on:
pull_request:
types: [opened, reopened, labeled, unlabeled, synchronize]
workflow_dispatch:
defaults:
run:
shell: bash
permissions:
contents: read
pull-requests: write
jobs:
changelog:
uses: dbt-labs/actions/.github/workflows/changelog-existence.yml@main
with:
changelog_comment: 'Thank you for your pull request! We could not find a changelog entry for this change. 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).'
skip_label: 'Skip Changelog'
secrets: inherit

View File

@@ -0,0 +1,41 @@
# **what?**
# Cuts a new `*.latest` branch
# Also cleans up all files in `.changes/unreleased` and `.changes/previous verion on
# `main` and bumps `main` to the input version.
# **why?**
# Generally reduces the workload of engineers and reduces error. Allow automation.
# **when?**
# This will run when called manually.
name: Cut new release branch
on:
workflow_dispatch:
inputs:
version_to_bump_main:
description: 'The alpha version main should bump to (ex. 1.6.0a1)'
required: true
new_branch_name:
description: 'The full name of the new branch (ex. 1.5.latest)'
required: true
defaults:
run:
shell: bash
permissions:
contents: write
jobs:
cut_branch:
name: "Cut branch and clean up main for dbt-core"
uses: dbt-labs/actions/.github/workflows/cut-release-branch.yml@main
with:
version_to_bump_main: ${{ inputs.version_to_bump_main }}
new_branch_name: ${{ inputs.new_branch_name }}
PR_title: "Cleanup main after cutting new ${{ inputs.new_branch_name }} branch"
PR_body: "All adapter PRs will fail CI until the dbt-core PR has been merged due to release version conflicts."
secrets:
FISHTOWN_BOT_PAT: ${{ secrets.FISHTOWN_BOT_PAT }}

View File

@@ -1,222 +0,0 @@
# **what?**
# This workflow runs all integration tests for supported OS
# and python versions and core adapters. If triggered by PR,
# the workflow will only run tests for adapters related
# to code changes. Use the `test all` and `test ${adapter}`
# label to run all or additional tests. Use `ok to test`
# label to mark PRs from forked repositories that are safe
# to run integration tests for. Requires secrets to run
# against different warehouses.
# **why?**
# This checks the functionality of dbt from a user's perspective
# and attempts to catch functional regressions.
# **when?**
# This workflow will run on every push to a protected branch
# and when manually triggered. It will also run for all PRs, including
# PRs from forks. The workflow will be skipped until there is a label
# to mark the PR as safe to run.
name: Adapter Integration Tests
on:
# pushes to release branches
push:
branches:
- "main"
- "develop"
- "*.latest"
- "releases/*"
# all PRs, important to note that `pull_request_target` workflows
# will run in the context of the target branch of a PR
pull_request_target:
# manual tigger
workflow_dispatch:
# explicitly turn off permissions for `GITHUB_TOKEN`
permissions: read-all
# will cancel previous workflows triggered by the same event and for the same ref for PRs or same SHA otherwise
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ contains(github.event_name, 'pull_request') && github.event.pull_request.head.ref || github.sha }}
cancel-in-progress: true
# sets default shell to bash, for all operating systems
defaults:
run:
shell: bash
jobs:
# generate test metadata about what files changed and the testing matrix to use
test-metadata:
# run if not a PR from a forked repository or has a label to mark as safe to test
if: >-
github.event_name != 'pull_request_target' ||
github.event.pull_request.head.repo.full_name == github.repository ||
contains(github.event.pull_request.labels.*.name, 'ok to test')
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate-matrix.outputs.result }}
steps:
- name: Check out the repository (non-PR)
if: github.event_name != 'pull_request_target'
uses: actions/checkout@v2
with:
persist-credentials: false
- name: Check out the repository (PR)
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v2
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}
- name: Check if relevant files changed
# https://github.com/marketplace/actions/paths-changes-filter
# For each filter, it sets output variable named by the filter to the text:
# 'true' - if any of changed files matches any of filter rules
# 'false' - if none of changed files matches any of filter rules
# also, returns:
# `changes` - JSON array with names of all filters matching any of the changed files
uses: dorny/paths-filter@v2
id: get-changes
with:
token: ${{ secrets.GITHUB_TOKEN }}
filters: |
postgres:
- 'core/**'
- 'plugins/postgres/**'
- 'dev-requirements.txt'
- name: Generate integration test matrix
id: generate-matrix
uses: actions/github-script@v4
env:
CHANGES: ${{ steps.get-changes.outputs.changes }}
with:
script: |
const script = require('./.github/scripts/integration-test-matrix.js')
const matrix = script({ context })
console.log(matrix)
return matrix
test:
name: ${{ matrix.adapter }} / python ${{ matrix.python-version }} / ${{ matrix.os }}
# run if not a PR from a forked repository or has a label to mark as safe to test
# also checks that the matrix generated is not empty
if: >-
needs.test-metadata.outputs.matrix &&
fromJSON( needs.test-metadata.outputs.matrix ).include[0] &&
(
github.event_name != 'pull_request_target' ||
github.event.pull_request.head.repo.full_name == github.repository ||
contains(github.event.pull_request.labels.*.name, 'ok to test')
)
runs-on: ${{ matrix.os }}
needs: test-metadata
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.test-metadata.outputs.matrix) }}
env:
TOXENV: integration-${{ matrix.adapter }}
PYTEST_ADDOPTS: "-v --color=yes -n4 --csv integration_results.csv"
DBT_INVOCATION_ENV: github-actions
steps:
- name: Check out the repository
if: github.event_name != 'pull_request_target'
uses: actions/checkout@v2
with:
persist-credentials: false
# explicity checkout the branch for the PR,
# this is necessary for the `pull_request_target` event
- name: Check out the repository (PR)
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v2
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Set up postgres (linux)
if: |
matrix.adapter == 'postgres' &&
runner.os == 'Linux'
uses: ./.github/actions/setup-postgres-linux
- name: Set up postgres (macos)
if: |
matrix.adapter == 'postgres' &&
runner.os == 'macOS'
uses: ./.github/actions/setup-postgres-macos
- name: Set up postgres (windows)
if: |
matrix.adapter == 'postgres' &&
runner.os == 'Windows'
uses: ./.github/actions/setup-postgres-windows
- name: Install python dependencies
run: |
pip install --user --upgrade pip
pip install tox
pip --version
tox --version
- name: Run tox (postgres)
if: matrix.adapter == 'postgres'
run: tox
- uses: actions/upload-artifact@v2
if: always()
with:
name: logs
path: ./logs
- name: Get current date
if: always()
id: date
run: echo "::set-output name=date::$(date +'%Y-%m-%dT%H_%M_%S')" #no colons allowed for artifacts
- uses: actions/upload-artifact@v2
if: always()
with:
name: integration_results_${{ matrix.python-version }}_${{ matrix.os }}_${{ matrix.adapter }}-${{ steps.date.outputs.date }}.csv
path: integration_results.csv
require-label-comment:
runs-on: ubuntu-latest
needs: test
permissions:
pull-requests: write
steps:
- name: Needs permission PR comment
if: >-
needs.test.result == 'skipped' &&
github.event_name == 'pull_request_target' &&
github.event.pull_request.head.repo.full_name != github.repository
uses: unsplash/comment-on-pr@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
msg: |
"You do not have permissions to run integration tests, @dbt-labs/core "\
"needs to label this PR with `ok to test` in order to run integration tests!"
check_for_duplicate_msg: true

View File

@@ -15,6 +15,9 @@ on:
issues:
types: [closed, deleted, reopened]
# no special access is needed
permissions: read-all
jobs:
call-label-action:
uses: dbt-labs/jira-actions/.github/workflows/jira-transition.yml@main

View File

@@ -1,9 +1,8 @@
# **what?**
# Runs code quality checks, unit tests, and verifies python build on
# all code commited to the repository. This workflow should not
# require any secrets since it runs for PRs from forked repos.
# By default, secrets are not passed to workflows running from
# a forked repo.
# Runs code quality checks, unit tests, integration tests and
# verifies python build on all code commited to the repository. This workflow
# should not require any secrets since it runs for PRs from forked repos. By
# default, secrets are not passed to workflows running from a forked repos.
# **why?**
# Ensure code for dbt meets a certain quality standard.
@@ -18,7 +17,6 @@ on:
push:
branches:
- "main"
- "develop"
- "*.latest"
- "releases/*"
pull_request:
@@ -35,29 +33,32 @@ defaults:
run:
shell: bash
# top-level adjustments can be made here
env:
# number of parallel processes to spawn for python integration testing
PYTHON_INTEGRATION_TEST_WORKERS: ${{ vars.PYTHON_INTEGRATION_TEST_WORKERS }}
jobs:
code-quality:
name: code-quality
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check out the repository
uses: actions/checkout@v2
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: '3.8'
- name: Install python dependencies
run: |
pip install --user --upgrade pip
pip install pre-commit
pip install mypy==0.782
pip install -r editable-requirements.txt
pip --version
pre-commit --version
python -m pip install --user --upgrade pip
python -m pip --version
make dev
mypy --version
dbt --version
@@ -68,11 +69,12 @@ jobs:
name: unit test / python ${{ matrix.python-version }}
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
env:
TOXENV: "unit"
@@ -80,20 +82,18 @@ jobs:
steps:
- name: Check out the repository
uses: actions/checkout@v2
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install python dependencies
run: |
pip install --user --upgrade pip
pip install tox
pip --version
python -m pip install --user --upgrade pip
python -m pip --version
python -m pip install tox
tox --version
- name: Run tox
@@ -102,14 +102,140 @@ jobs:
- name: Get current date
if: always()
id: date
run: echo "::set-output name=date::$(date +'%Y-%m-%dT%H_%M_%S')" #no colons allowed for artifacts
run: |
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@v4
if: always()
with:
name: unit_results_${{ matrix.python-version }}-${{ steps.date.outputs.date }}.csv
path: unit_results.csv
integration-metadata:
name: integration test metadata generation
runs-on: ubuntu-latest
outputs:
split-groups: ${{ steps.generate-split-groups.outputs.split-groups }}
include: ${{ steps.generate-include.outputs.include }}
steps:
- name: generate split-groups
id: generate-split-groups
run: |
MATRIX_JSON="["
for B in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do
MATRIX_JSON+=$(sed 's/^/"/;s/$/"/' <<< "${B}")
done
MATRIX_JSON="${MATRIX_JSON//\"\"/\", \"}"
MATRIX_JSON+="]"
echo "split-groups=${MATRIX_JSON}"
echo "split-groups=${MATRIX_JSON}" >> $GITHUB_OUTPUT
- name: generate include
id: generate-include
run: |
INCLUDE=('"python-version":"3.8","os":"windows-latest"' '"python-version":"3.8","os":"macos-latest"' )
INCLUDE_GROUPS="["
for include in ${INCLUDE[@]}; do
for group in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do
INCLUDE_GROUPS+=$(sed 's/$/, /' <<< "{\"split-group\":\"${group}\",${include}}")
done
done
INCLUDE_GROUPS=$(echo $INCLUDE_GROUPS | sed 's/,*$//g')
INCLUDE_GROUPS+="]"
echo "include=${INCLUDE_GROUPS}"
echo "include=${INCLUDE_GROUPS}" >> $GITHUB_OUTPUT
integration:
name: (${{ matrix.split-group }}) integration test / python ${{ matrix.python-version }} / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 30
needs:
- integration-metadata
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
os: [ubuntu-20.04]
split-group: ${{ fromJson(needs.integration-metadata.outputs.split-groups) }}
include: ${{ fromJson(needs.integration-metadata.outputs.include) }}
env:
TOXENV: integration
PYTEST_ADDOPTS: "-v --color=yes -n4 --csv integration_results.csv"
DBT_INVOCATION_ENV: github-actions
DBT_TEST_USER_1: dbt_test_user_1
DBT_TEST_USER_2: dbt_test_user_2
DBT_TEST_USER_3: dbt_test_user_3
DD_CIVISIBILITY_AGENTLESS_ENABLED: true
DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
DD_SITE: datadoghq.com
DD_ENV: ci
DD_SERVICE: ${{ github.event.repository.name }}
steps:
- name: Check out the repository
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up postgres (linux)
if: runner.os == 'Linux'
uses: ./.github/actions/setup-postgres-linux
- name: Set up postgres (macos)
if: runner.os == 'macOS'
uses: ./.github/actions/setup-postgres-macos
- name: Set up postgres (windows)
if: runner.os == 'Windows'
uses: ./.github/actions/setup-postgres-windows
- name: Install python tools
run: |
python -m pip install --user --upgrade pip
python -m pip --version
python -m pip install tox
tox --version
- name: Run tests
run: tox -- --ddtrace
env:
PYTEST_ADDOPTS: ${{ format('--splits {0} --group {1}', env.PYTHON_INTEGRATION_TEST_WORKERS, matrix.split-group) }}
- name: Get current date
if: always()
id: date
run: |
CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts
echo "date=$CURRENT_DATE" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v4
if: always()
with:
name: logs_${{ matrix.python-version }}_${{ matrix.os }}_${{ matrix.split-group }}_${{ steps.date.outputs.date }}
path: ./logs
- uses: actions/upload-artifact@v4
if: always()
with:
name: integration_results_${{ matrix.python-version }}_${{ matrix.os }}_${{ steps.date.outputs.date }}.csv
path: integration_results.csv
integration-report:
if: ${{ always() }}
name: Integration Test Suite
runs-on: ubuntu-latest
needs: integration
steps:
- name: "[Notification] Integration test suite passes"
run: |
echo "::notice title="Integration test suite passes""
build:
name: build packages
@@ -117,20 +243,18 @@ jobs:
steps:
- name: Check out the repository
uses: actions/checkout@v2
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: '3.8'
- name: Install python dependencies
run: |
pip install --user --upgrade pip
pip install --upgrade setuptools wheel twine check-wheel-contents
pip --version
python -m pip install --user --upgrade pip
python -m pip install --upgrade setuptools wheel twine check-wheel-contents
python -m pip --version
- name: Build distributions
run: ./scripts/build-dist.sh
@@ -146,47 +270,9 @@ jobs:
run: |
check-wheel-contents dist/*.whl --ignore W007,W008
- uses: actions/upload-artifact@v2
with:
name: dist
path: dist/
test-build:
name: verify packages / python ${{ matrix.python-version }} / ${{ matrix.os }}
needs: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.7, 3.8, 3.9]
steps:
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install python dependencies
run: |
pip install --user --upgrade pip
pip install --upgrade wheel
pip --version
- uses: actions/download-artifact@v2
with:
name: dist
path: dist/
- name: Show distributions
run: ls -lh dist/
- name: Install wheel distributions
run: |
find ./dist/*.whl -maxdepth 1 -type f | xargs pip install --force-reinstall --find-links=dist/
find ./dist/*.whl -maxdepth 1 -type f | xargs python -m pip install --force-reinstall --find-links=dist/
- name: Check wheel distributions
run: |
@@ -195,7 +281,7 @@ jobs:
- name: Install source distributions
# ignore dbt-1.0.0, which intentionally raises an error when installed from source
run: |
find ./dist/dbt-[a-z]*.gz -maxdepth 1 -type f | xargs pip install --force-reinstall --find-links=dist/
find ./dist/*.gz -maxdepth 1 -type f | xargs python -m pip install --force-reinstall --find-links=dist/
- name: Check source distributions
run: |

109
.github/workflows/nightly-release.yml vendored Normal file
View File

@@ -0,0 +1,109 @@
# **what?**
# Nightly releases to GitHub and PyPI. This workflow produces the following outcome:
# - generate and validate data for night release (commit SHA, version number, release branch);
# - pass data to release workflow;
# - night release will be pushed to GitHub as a draft release;
# - night build will be pushed to test PyPI;
#
# **why?**
# Ensure an automated and tested release process for nightly builds
#
# **when?**
# This workflow runs on schedule or can be run manually on demand.
name: Nightly Test Release to GitHub and PyPI
on:
workflow_dispatch: # for manual triggering
schedule:
- cron: 0 9 * * *
permissions:
contents: write # this is the permission that allows creating a new release
defaults:
run:
shell: bash
env:
RELEASE_BRANCH: "main"
jobs:
aggregate-release-data:
runs-on: ubuntu-latest
outputs:
commit_sha: ${{ steps.resolve-commit-sha.outputs.release_commit }}
version_number: ${{ steps.nightly-release-version.outputs.number }}
release_branch: ${{ steps.release-branch.outputs.name }}
steps:
- name: "Checkout ${{ github.repository }} Branch ${{ env.RELEASE_BRANCH }}"
uses: actions/checkout@v4
with:
ref: ${{ env.RELEASE_BRANCH }}
- name: "Resolve Commit To Release"
id: resolve-commit-sha
run: |
commit_sha=$(git rev-parse HEAD)
echo "release_commit=$commit_sha" >> $GITHUB_OUTPUT
- name: "Get Current Version Number"
id: version-number-sources
run: |
current_version=`awk -F"current_version = " '{print $2}' .bumpversion.cfg | tr '\n' ' '`
echo "current_version=$current_version" >> $GITHUB_OUTPUT
- name: "Audit Version And Parse Into Parts"
id: semver
uses: dbt-labs/actions/parse-semver@v1.1.0
with:
version: ${{ steps.version-number-sources.outputs.current_version }}
- name: "Get Current Date"
id: current-date
run: echo "date=$(date +'%m%d%Y')" >> $GITHUB_OUTPUT
- name: "Generate Nightly Release Version Number"
id: nightly-release-version
run: |
number="${{ steps.semver.outputs.version }}.dev${{ steps.current-date.outputs.date }}"
echo "number=$number" >> $GITHUB_OUTPUT
- name: "Audit Nightly Release Version And Parse Into Parts"
uses: dbt-labs/actions/parse-semver@v1.1.0
with:
version: ${{ steps.nightly-release-version.outputs.number }}
- name: "Set Release Branch"
id: release-branch
run: |
echo "name=${{ env.RELEASE_BRANCH }}" >> $GITHUB_OUTPUT
log-outputs-aggregate-release-data:
runs-on: ubuntu-latest
needs: [aggregate-release-data]
steps:
- name: "[DEBUG] Log Outputs"
run: |
echo commit_sha : ${{ needs.aggregate-release-data.outputs.commit_sha }}
echo version_number: ${{ needs.aggregate-release-data.outputs.version_number }}
echo release_branch: ${{ needs.aggregate-release-data.outputs.release_branch }}
release-github-pypi:
needs: [aggregate-release-data]
uses: ./.github/workflows/release.yml
with:
sha: ${{ needs.aggregate-release-data.outputs.commit_sha }}
target_branch: ${{ needs.aggregate-release-data.outputs.release_branch }}
version_number: ${{ needs.aggregate-release-data.outputs.version_number }}
build_script_path: "scripts/build-dist.sh"
env_setup_script_path: "scripts/env-setup.sh"
s3_bucket_name: "core-team-artifacts"
package_test_command: "dbt --version"
test_run: true
nightly_release: true
secrets: inherit

View File

@@ -1,176 +0,0 @@
name: Performance Regression Tests
# Schedule triggers
on:
# runs twice a day at 10:05am and 10:05pm
schedule:
- cron: "5 10,22 * * *"
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# checks fmt of runner code
# purposefully not a dependency of any other job
# will block merging, but not prevent developing
fmt:
name: Cargo fmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- run: rustup component add rustfmt
- uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path performance/runner/Cargo.toml --all -- --check
# runs any tests associated with the runner
# these tests make sure the runner logic is correct
test-runner:
name: Test Runner
runs-on: ubuntu-latest
env:
# turns errors into warnings
RUSTFLAGS: "-D warnings"
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path performance/runner/Cargo.toml
# build an optimized binary to be used as the runner in later steps
build-runner:
needs: [test-runner]
name: Build Runner
runs-on: ubuntu-latest
env:
RUSTFLAGS: "-D warnings"
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: build
args: --release --manifest-path performance/runner/Cargo.toml
- uses: actions/upload-artifact@v2
with:
name: runner
path: performance/runner/target/release/runner
# run the performance measurements on the current or default branch
measure-dev:
needs: [build-runner]
name: Measure Dev Branch
runs-on: ubuntu-latest
steps:
- name: checkout dev
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2.2.2
with:
python-version: "3.8"
- name: install dbt
run: pip install -r dev-requirements.txt -r editable-requirements.txt
- name: install hyperfine
run: wget https://github.com/sharkdp/hyperfine/releases/download/v1.11.0/hyperfine_1.11.0_amd64.deb && sudo dpkg -i hyperfine_1.11.0_amd64.deb
- uses: actions/download-artifact@v2
with:
name: runner
- name: change permissions
run: chmod +x ./runner
- name: run
run: ./runner measure -b dev -p ${{ github.workspace }}/performance/projects/
- uses: actions/upload-artifact@v2
with:
name: dev-results
path: performance/results/
# run the performance measurements on the release branch which we use
# as a performance baseline. This part takes by far the longest, so
# we do everything we can first so the job fails fast.
# -----
# we need to checkout dbt twice in this job: once for the baseline dbt
# version, and once to get the latest regression testing projects,
# metrics, and runner code from the develop or current branch so that
# the calculations match for both versions of dbt we are comparing.
measure-baseline:
needs: [build-runner]
name: Measure Baseline Branch
runs-on: ubuntu-latest
steps:
- name: checkout latest
uses: actions/checkout@v2
with:
ref: "0.20.latest"
- name: Setup Python
uses: actions/setup-python@v2.2.2
with:
python-version: "3.8"
- name: move repo up a level
run: mkdir ${{ github.workspace }}/../baseline/ && cp -r ${{ github.workspace }} ${{ github.workspace }}/../baseline
- name: "[debug] ls new dbt location"
run: ls ${{ github.workspace }}/../baseline/dbt/
# installation creates egg-links so we have to preserve source
- name: install dbt from new location
run: cd ${{ github.workspace }}/../baseline/dbt/ && pip install -r dev-requirements.txt -r editable-requirements.txt
# checkout the current branch to get all the target projects
# this deletes the old checked out code which is why we had to copy before
- name: checkout dev
uses: actions/checkout@v2
- name: install hyperfine
run: wget https://github.com/sharkdp/hyperfine/releases/download/v1.11.0/hyperfine_1.11.0_amd64.deb && sudo dpkg -i hyperfine_1.11.0_amd64.deb
- uses: actions/download-artifact@v2
with:
name: runner
- name: change permissions
run: chmod +x ./runner
- name: run runner
run: ./runner measure -b baseline -p ${{ github.workspace }}/performance/projects/
- uses: actions/upload-artifact@v2
with:
name: baseline-results
path: performance/results/
# detect regressions on the output generated from measuring
# the two branches. Exits with non-zero code if a regression is detected.
calculate-regressions:
needs: [measure-dev, measure-baseline]
name: Compare Results
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v2
with:
name: dev-results
- uses: actions/download-artifact@v2
with:
name: baseline-results
- name: "[debug] ls result files"
run: ls
- uses: actions/download-artifact@v2
with:
name: runner
- name: change permissions
run: chmod +x ./runner
- name: make results directory
run: mkdir ./final-output/
- name: run calculation
run: ./runner calculate -r ./ -o ./final-output/
# always attempt to upload the results even if there were regressions found
- uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: final-calculations
path: ./final-output/*

View File

@@ -0,0 +1,90 @@
# **what?**
# The purpose of this workflow is to trigger CI to run for each
# release branch and main branch on a regular cadence. If the CI workflow
# fails for a branch, it will post to dev-core-alerts to raise awareness.
# The 'aurelien-baudet/workflow-dispatch' Action triggers the existing
# CI worklow file on the given branch to run so that even if we change the
# CI workflow file in the future, the one that is tailored for the given
# release branch will be used.
# **why?**
# Ensures release branches and main are always shippable and not broken.
# Also, can catch any dependencies shifting beneath us that might
# introduce breaking changes (could also impact Cloud).
# **when?**
# Mainly on a schedule of 9:00, 13:00, 18:00 UTC everyday.
# Manual trigger can also test on demand
name: Release branch scheduled testing
on:
schedule:
- cron: '0 9,13,18 * * *' # 9:00, 13:00, 18:00 UTC
workflow_dispatch: # for manual triggering
# no special access is needed
permissions: read-all
jobs:
fetch-latest-branches:
runs-on: ubuntu-latest
outputs:
latest-branches: ${{ steps.get-latest-branches.outputs.repo-branches }}
steps:
- name: "Fetch dbt-core Latest Branches"
uses: dbt-labs/actions/fetch-repo-branches@v1.1.1
id: get-latest-branches
with:
repo_name: ${{ github.event.repository.name }}
organization: "dbt-labs"
pat: ${{ secrets.GITHUB_TOKEN }}
fetch_protected_branches_only: true
regex: "^1.[0-9]+.latest$"
perform_match_method: "match"
retries: 3
- name: "[ANNOTATION] ${{ github.event.repository.name }} - branches to test"
run: |
title="${{ github.event.repository.name }} - branches to test"
message="The workflow will run tests for the following branches of the ${{ github.event.repository.name }} repo: ${{ steps.get-latest-branches.outputs.repo-branches }}"
echo "::notice $title::$message"
kick-off-ci:
needs: [fetch-latest-branches]
name: Kick-off CI
runs-on: ubuntu-latest
strategy:
# must run CI 1 branch at a time b/c the workflow-dispatch Action polls for
# latest run for results and it gets confused when we kick off multiple runs
# at once. There is a race condition so we will just run in sequential order.
max-parallel: 1
fail-fast: false
matrix:
branch: ${{ fromJSON(needs.fetch-latest-branches.outputs.latest-branches) }}
include:
- branch: 'main'
steps:
- name: Call CI workflow for ${{ matrix.branch }} branch
id: trigger-step
uses: aurelien-baudet/workflow-dispatch@v2.1.1
with:
workflow: main.yml
ref: ${{ matrix.branch }}
token: ${{ secrets.FISHTOWN_BOT_PAT }}
- name: Post failure to Slack
uses: ravsamhq/notify-slack-action@v1
if: ${{ always() && !contains(steps.trigger-step.outputs.workflow-conclusion,'success') }}
with:
status: ${{ job.status }}
notification_title: 'dbt-core scheduled run of "${{ matrix.branch }}" branch not successful'
message_format: ':x: CI on branch "${{ matrix.branch }}" ${{ steps.trigger-step.outputs.workflow-conclusion }}'
footer: 'Linked failed CI run ${{ steps.trigger-step.outputs.workflow-url }}'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEV_CORE_ALERTS }}

View File

@@ -12,6 +12,9 @@
name: Docker release
permissions:
packages: write
on:
workflow_dispatch:
inputs:
@@ -33,14 +36,14 @@ jobs:
latest: ${{ steps.latest.outputs.latest }}
minor_latest: ${{ steps.latest.outputs.minor_latest }}
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- name: Split version
id: version
run: |
IFS="." read -r MAJOR MINOR PATCH <<< ${{ github.event.inputs.version_number }}
echo "::set-output name=major::$MAJOR"
echo "::set-output name=minor::$MINOR"
echo "::set-output name=patch::$PATCH"
echo "major=$MAJOR" >> $GITHUB_OUTPUT
echo "minor=$MINOR" >> $GITHUB_OUTPUT
echo "patch=$PATCH" >> $GITHUB_OUTPUT
- name: Is pkg 'latest'
id: latest
@@ -57,7 +60,7 @@ jobs:
needs: [get_version_meta]
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
build_and_push:
name: Build images and push to GHCR
@@ -67,18 +70,20 @@ jobs:
- name: Get docker build arg
id: build_arg
run: |
echo "::set-output name=build_arg_name::"$(echo ${{ github.event.inputs.package }} | sed 's/\-/_/g')
echo "::set-output name=build_arg_value::"$(echo ${{ github.event.inputs.package }} | sed 's/postgres/core/g')
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 "build_arg_name=$BUILD_ARG_NAME" >> $GITHUB_OUTPUT
echo "build_arg_value=$BUILD_ARG_VALUE" >> $GITHUB_OUTPUT
- name: Log in to the GHCR
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push MAJOR.MINOR.PATCH tag
uses: docker/build-push-action@v2
uses: docker/build-push-action@v4
with:
file: docker/Dockerfile
push: True
@@ -89,7 +94,7 @@ jobs:
ghcr.io/dbt-labs/${{ github.event.inputs.package }}:${{ github.event.inputs.version_number }}
- name: Build and push MINOR.latest tag
uses: docker/build-push-action@v2
uses: docker/build-push-action@v4
if: ${{ needs.get_version_meta.outputs.minor_latest == 'True' }}
with:
file: docker/Dockerfile
@@ -101,7 +106,7 @@ jobs:
ghcr.io/dbt-labs/${{ github.event.inputs.package }}:${{ needs.get_version_meta.outputs.major }}.${{ needs.get_version_meta.outputs.minor }}.latest
- name: Build and push latest tag
uses: docker/build-push-action@v2
uses: docker/build-push-action@v4
if: ${{ needs.get_version_meta.outputs.latest == 'True' }}
with:
file: docker/Dockerfile

View File

@@ -1,199 +1,229 @@
# **what?**
# Take the given commit, run unit tests specifically on that sha, build and
# package it, and then release to GitHub and PyPi with that specific build
# Release workflow provides the following steps:
# - checkout the given commit;
# - validate version in sources and changelog file for given version;
# - bump the version and generate a changelog if needed;
# - merge all changes to the target branch if needed;
# - run unit and integration tests against given commit;
# - build and package that SHA;
# - release it to GitHub and PyPI with that specific build;
#
# **why?**
# Ensure an automated and tested release process
#
# **when?**
# This will only run manually with a given sha and version
# This workflow can be run manually on demand or can be called by other workflows
name: Release to GitHub and PyPi
name: Release to GitHub and PyPI
on:
workflow_dispatch:
inputs:
sha:
description: 'The last commit sha in the release'
required: true
description: "The last commit sha in the release"
type: string
required: true
target_branch:
description: "The branch to release from"
type: string
required: true
version_number:
description: 'The release version number (i.e. 1.0.0b1)'
required: true
description: "The release version number (i.e. 1.0.0b1)"
type: string
required: true
build_script_path:
description: "Build script path"
type: string
default: "scripts/build-dist.sh"
required: true
env_setup_script_path:
description: "Environment setup script path"
type: string
default: "scripts/env-setup.sh"
required: false
s3_bucket_name:
description: "AWS S3 bucket name"
type: string
default: "core-team-artifacts"
required: true
package_test_command:
description: "Package test command"
type: string
default: "dbt --version"
required: true
test_run:
description: "Test run (Publish release as draft)"
type: boolean
default: true
required: false
nightly_release:
description: "Nightly release to dev environment"
type: boolean
default: false
required: false
workflow_call:
inputs:
sha:
description: "The last commit sha in the release"
type: string
required: true
target_branch:
description: "The branch to release from"
type: string
required: true
version_number:
description: "The release version number (i.e. 1.0.0b1)"
type: string
required: true
build_script_path:
description: "Build script path"
type: string
default: "scripts/build-dist.sh"
required: true
env_setup_script_path:
description: "Environment setup script path"
type: string
default: "scripts/env-setup.sh"
required: false
s3_bucket_name:
description: "AWS S3 bucket name"
type: string
default: "core-team-artifacts"
required: true
package_test_command:
description: "Package test command"
type: string
default: "dbt --version"
required: true
test_run:
description: "Test run (Publish release as draft)"
type: boolean
default: true
required: false
nightly_release:
description: "Nightly release to dev environment"
type: boolean
default: false
required: false
permissions:
contents: write # this is the permission that allows creating a new release
defaults:
run:
shell: bash
jobs:
unit:
name: Unit test
log-inputs:
name: Log Inputs
runs-on: ubuntu-latest
env:
TOXENV: "unit"
steps:
- name: Check out the repository
uses: actions/checkout@v2
with:
persist-credentials: false
ref: ${{ github.event.inputs.sha }}
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install python dependencies
- name: "[DEBUG] Print Variables"
run: |
pip install --user --upgrade pip
pip install tox
pip --version
tox --version
echo The last commit sha in the release: ${{ inputs.sha }}
echo The branch to release from: ${{ inputs.target_branch }}
echo The release version number: ${{ inputs.version_number }}
echo Build script path: ${{ inputs.build_script_path }}
echo Environment setup script path: ${{ inputs.env_setup_script_path }}
echo AWS S3 bucket name: ${{ inputs.s3_bucket_name }}
echo Package test command: ${{ inputs.package_test_command }}
echo Test run: ${{ inputs.test_run }}
echo Nightly release: ${{ inputs.nightly_release }}
- name: Run tox
run: tox
bump-version-generate-changelog:
name: Bump package version, Generate changelog
build:
name: build packages
uses: dbt-labs/dbt-release/.github/workflows/release-prep.yml@main
with:
sha: ${{ inputs.sha }}
version_number: ${{ inputs.version_number }}
target_branch: ${{ inputs.target_branch }}
env_setup_script_path: ${{ inputs.env_setup_script_path }}
test_run: ${{ inputs.test_run }}
nightly_release: ${{ inputs.nightly_release }}
secrets: inherit
log-outputs-bump-version-generate-changelog:
name: "[Log output] Bump package version, Generate changelog"
if: ${{ !failure() && !cancelled() }}
needs: [bump-version-generate-changelog]
runs-on: ubuntu-latest
steps:
- name: Check out the repository
uses: actions/checkout@v2
with:
persist-credentials: false
ref: ${{ github.event.inputs.sha }}
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install python dependencies
- name: Print variables
run: |
pip install --user --upgrade pip
pip install --upgrade setuptools wheel twine check-wheel-contents
pip --version
echo Final SHA : ${{ needs.bump-version-generate-changelog.outputs.final_sha }}
echo Changelog path: ${{ needs.bump-version-generate-changelog.outputs.changelog_path }}
- name: Build distributions
run: ./scripts/build-dist.sh
build-test-package:
name: Build, Test, Package
if: ${{ !failure() && !cancelled() }}
needs: [bump-version-generate-changelog]
- name: Show distributions
run: ls -lh dist/
uses: dbt-labs/dbt-release/.github/workflows/build.yml@main
- name: Check distribution descriptions
run: |
twine check dist/*
with:
sha: ${{ needs.bump-version-generate-changelog.outputs.final_sha }}
version_number: ${{ inputs.version_number }}
changelog_path: ${{ needs.bump-version-generate-changelog.outputs.changelog_path }}
build_script_path: ${{ inputs.build_script_path }}
s3_bucket_name: ${{ inputs.s3_bucket_name }}
package_test_command: ${{ inputs.package_test_command }}
test_run: ${{ inputs.test_run }}
nightly_release: ${{ inputs.nightly_release }}
- name: Check wheel contents
run: |
check-wheel-contents dist/*.whl --ignore W007,W008
- uses: actions/upload-artifact@v2
with:
name: dist
path: |
dist/
!dist/dbt-${{github.event.inputs.version_number}}.tar.gz
test-build:
name: verify packages
needs: [build, unit]
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install python dependencies
run: |
pip install --user --upgrade pip
pip install --upgrade wheel
pip --version
- uses: actions/download-artifact@v2
with:
name: dist
path: dist/
- name: Show distributions
run: ls -lh dist/
- name: Install wheel distributions
run: |
find ./dist/*.whl -maxdepth 1 -type f | xargs pip install --force-reinstall --find-links=dist/
- name: Check wheel distributions
run: |
dbt --version
- name: Install source distributions
run: |
find ./dist/*.gz -maxdepth 1 -type f | xargs pip install --force-reinstall --find-links=dist/
- name: Check source distributions
run: |
dbt --version
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
github-release:
name: GitHub Release
if: ${{ !failure() && !cancelled() }}
needs: test-build
needs: [bump-version-generate-changelog, build-test-package]
runs-on: ubuntu-latest
uses: dbt-labs/dbt-release/.github/workflows/github-release.yml@main
steps:
- uses: actions/download-artifact@v2
with:
name: dist
path: '.'
# Need to set an output variable because env variables can't be taken as input
# This is needed for the next step with releasing to GitHub
- name: Find release type
id: release_type
env:
IS_PRERELEASE: ${{ contains(github.event.inputs.version_number, 'rc') || contains(github.event.inputs.version_number, 'b') }}
run: |
echo ::set-output name=isPrerelease::$IS_PRERELEASE
- name: Creating GitHub Release
uses: softprops/action-gh-release@v1
with:
name: dbt-core v${{github.event.inputs.version_number}}
tag_name: v${{github.event.inputs.version_number}}
prerelease: ${{ steps.release_type.outputs.isPrerelease }}
target_commitish: ${{github.event.inputs.sha}}
body: |
[Release notes](https://github.com/dbt-labs/dbt-core/blob/main/CHANGELOG.md)
files: |
dbt_postgres-${{github.event.inputs.version_number}}-py3-none-any.whl
dbt_core-${{github.event.inputs.version_number}}-py3-none-any.whl
dbt-postgres-${{github.event.inputs.version_number}}.tar.gz
dbt-core-${{github.event.inputs.version_number}}.tar.gz
with:
sha: ${{ needs.bump-version-generate-changelog.outputs.final_sha }}
version_number: ${{ inputs.version_number }}
changelog_path: ${{ needs.bump-version-generate-changelog.outputs.changelog_path }}
test_run: ${{ inputs.test_run }}
pypi-release:
name: Pypi release
name: PyPI Release
runs-on: ubuntu-latest
needs: [github-release]
needs: github-release
uses: dbt-labs/dbt-release/.github/workflows/pypi-release.yml@main
environment: PypiProd
steps:
- uses: actions/download-artifact@v2
with:
name: dist
path: 'dist'
with:
version_number: ${{ inputs.version_number }}
test_run: ${{ inputs.test_run }}
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@v1.4.2
with:
password: ${{ secrets.PYPI_API_TOKEN }}
secrets:
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
TEST_PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
slack-notification:
name: Slack Notification
if: ${{ failure() && (!inputs.test_run || inputs.nightly_release) }}
needs:
[
bump-version-generate-changelog,
build-test-package,
github-release,
pypi-release,
]
uses: dbt-labs/dbt-release/.github/workflows/slack-post-notification.yml@main
with:
status: "failure"
secrets:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEV_CORE_ALERTS }}

View File

@@ -21,6 +21,9 @@ on:
- "*.latest"
- "releases/*"
# no special access is needed
permissions: read-all
env:
LATEST_SCHEMA_PATH: ${{ github.workspace }}/new_schemas
SCHEMA_DIFF_ARTIFACT: ${{ github.workspace }}//schema_schanges.txt
@@ -34,17 +37,17 @@ jobs:
steps:
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: 3.8
- name: Checkout dbt repo
uses: actions/checkout@v2.3.4
uses: actions/checkout@v4
with:
path: ${{ env.DBT_REPO_DIRECTORY }}
- name: Checkout schemas.getdbt.com repo
uses: actions/checkout@v2.3.4
uses: actions/checkout@v4
with:
repository: dbt-labs/schemas.getdbt.com
ref: 'main'
@@ -80,7 +83,7 @@ jobs:
fi
- name: Upload schema diff
uses: actions/upload-artifact@v2.2.4
uses: actions/upload-artifact@v4
if: ${{ failure() }}
with:
name: 'schema_schanges.txt'

View File

@@ -3,16 +3,10 @@ on:
schedule:
- cron: "30 1 * * *"
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
# pinned at v4 (https://github.com/actions/stale/releases/tag/v4.0.0)
- uses: actions/stale@cdf15f641adb27a71842045a94023bef6945e3aa
with:
stale-issue-message: "This issue has been marked as Stale because it has been open for 180 days with no activity. If you would like the issue to remain open, please remove the stale label or comment on the issue, or it will be closed in 7 days."
stale-pr-message: "This PR has been marked as Stale because it has been open for 180 days with no activity. If you would like the PR to remain open, please remove the stale label or comment on the PR, or it will be closed in 7 days."
# mark issues/PRs stale when they haven't seen activity in 180 days
days-before-stale: 180
# ignore checking issues with the following labels
exempt-issue-labels: "epic,discussion"
uses: dbt-labs/actions/.github/workflows/stale-bot-matrix.yml@main

View File

@@ -6,7 +6,6 @@
# version of our structured logging and add new documentation to
# communicate these changes.
name: Structured Logging Schema Check
on:
push:
@@ -19,38 +18,72 @@ on:
permissions: read-all
# top-level adjustments can be made here
env:
# number of parallel processes to spawn for python testing
PYTHON_INTEGRATION_TEST_WORKERS: ${{ vars.PYTHON_INTEGRATION_TEST_WORKERS }}
jobs:
integration-metadata:
name: integration test metadata generation
runs-on: ubuntu-latest
outputs:
split-groups: ${{ steps.generate-split-groups.outputs.split-groups }}
steps:
- name: generate split-groups
id: generate-split-groups
run: |
MATRIX_JSON="["
for B in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do
MATRIX_JSON+=$(sed 's/^/"/;s/$/"/' <<< "${B}")
done
MATRIX_JSON="${MATRIX_JSON//\"\"/\", \"}"
MATRIX_JSON+="]"
echo "split-groups=${MATRIX_JSON}" >> $GITHUB_OUTPUT
# run the performance measurements on the current or default branch
test-schema:
name: Test Log Schema
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
timeout-minutes: 30
needs:
- integration-metadata
strategy:
fail-fast: false
matrix:
split-group: ${{ fromJson(needs.integration-metadata.outputs.split-groups) }}
env:
# turns warnings into errors
RUSTFLAGS: "-D warnings"
# points tests to the log file
LOG_DIR: "/home/runner/work/dbt-core/dbt-core/logs"
# tells integration tests to output into json format
DBT_LOG_FORMAT: 'json'
steps:
DBT_LOG_FORMAT: "json"
# tell eventmgr to convert logging events into bytes
DBT_TEST_BINARY_SERIALIZATION: "true"
# Additional test users
DBT_TEST_USER_1: dbt_test_user_1
DBT_TEST_USER_2: dbt_test_user_2
DBT_TEST_USER_3: dbt_test_user_3
steps:
- name: checkout dev
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Python
uses: actions/setup-python@v2.2.2
uses: actions/setup-python@v5
with:
python-version: "3.8"
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: install dbt
run: pip install -r dev-requirements.txt -r editable-requirements.txt
- name: Install python dependencies
run: |
pip install --user --upgrade pip
pip --version
pip install tox
tox --version
- name: Set up postgres
uses: ./.github/actions/setup-postgres-linux
@@ -61,11 +94,15 @@ jobs:
# integration tests generate a ton of logs in different files. the next step will find them all.
# we actually care if these pass, because the normal test run doesn't usually include many json log outputs
- name: Run integration tests
run: tox -e py38-postgres -- -nauto
run: tox -e integration -- -nauto
env:
PYTEST_ADDOPTS: ${{ format('--splits {0} --group {1}', env.PYTHON_INTEGRATION_TEST_WORKERS, matrix.split-group) }}
# apply our schema tests to every log event from the previous step
# skips any output that isn't valid json
- uses: actions-rs/cargo@v1
with:
command: run
args: --manifest-path test/interop/log_parsing/Cargo.toml
test-schema-report:
name: Log Schema Test Suite
runs-on: ubuntu-latest
needs: test-schema
steps:
- name: "[Notification] Log test suite passes"
run: |
echo "::notice title="Log test suite passes""

155
.github/workflows/test-repeater.yml vendored Normal file
View File

@@ -0,0 +1,155 @@
# **what?**
# This workflow will test all test(s) at the input path given number of times to determine if it's flaky or not. You can test with any supported OS/Python combination.
# This is batched in 10 to allow more test iterations faster.
# **why?**
# Testing if a test is flaky and if a previously flaky test has been fixed. This allows easy testing on supported python versions and OS combinations.
# **when?**
# This is triggered manually from dbt-core.
name: Flaky Tester
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to check out'
type: string
required: true
default: 'main'
test_path:
description: 'Path to single test to run (ex: tests/functional/retry/test_retry.py::TestRetry::test_fail_fast)'
type: string
required: true
default: 'tests/functional/...'
python_version:
description: 'Version of Python to Test Against'
type: choice
options:
- '3.8'
- '3.9'
- '3.10'
- '3.11'
os:
description: 'OS to run test in'
type: choice
options:
- 'ubuntu-latest'
- 'macos-latest'
- 'windows-latest'
num_runs_per_batch:
description: 'Max number of times to run the test per batch. We always run 10 batches.'
type: number
required: true
default: '50'
permissions: read-all
defaults:
run:
shell: bash
jobs:
debug:
runs-on: ubuntu-latest
steps:
- name: "[DEBUG] Output Inputs"
run: |
echo "Branch: ${{ inputs.branch }}"
echo "test_path: ${{ inputs.test_path }}"
echo "python_version: ${{ inputs.python_version }}"
echo "os: ${{ inputs.os }}"
echo "num_runs_per_batch: ${{ inputs.num_runs_per_batch }}"
pytest:
runs-on: ${{ inputs.os }}
strategy:
# run all batches, even if one fails. This informs how flaky the test may be.
fail-fast: false
# using a matrix to speed up the jobs since the matrix will run in parallel when runners are available
matrix:
batch: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
env:
PYTEST_ADDOPTS: "-v --color=yes -n4 --csv integration_results.csv"
DBT_TEST_USER_1: dbt_test_user_1
DBT_TEST_USER_2: dbt_test_user_2
DBT_TEST_USER_3: dbt_test_user_3
DD_CIVISIBILITY_AGENTLESS_ENABLED: true
DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
DD_SITE: datadoghq.com
DD_ENV: ci
DD_SERVICE: ${{ github.event.repository.name }}
steps:
- name: "Checkout code"
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch }}
- name: "Setup Python"
uses: actions/setup-python@v5
with:
python-version: "${{ inputs.python_version }}"
- name: "Setup Dev Environment"
run: make dev
- name: "Set up postgres (linux)"
if: inputs.os == 'ubuntu-latest'
run: make setup-db
# mac and windows don't use make due to limitations with docker with those runners in GitHub
- name: "Set up postgres (macos)"
if: inputs.os == 'macos-latest'
uses: ./.github/actions/setup-postgres-macos
- name: "Set up postgres (windows)"
if: inputs.os == 'windows-latest'
uses: ./.github/actions/setup-postgres-windows
- name: "Test Command"
id: command
run: |
test_command="python -m pytest ${{ inputs.test_path }}"
echo "test_command=$test_command" >> $GITHUB_OUTPUT
- name: "Run test ${{ inputs.num_runs_per_batch }} times"
id: pytest
run: |
set +e
for ((i=1; i<=${{ inputs.num_runs_per_batch }}; i++))
do
echo "Running pytest iteration $i..."
python -m pytest --ddtrace ${{ inputs.test_path }}
exit_code=$?
if [[ $exit_code -eq 0 ]]; then
success=$((success + 1))
echo "Iteration $i: Success"
else
failure=$((failure + 1))
echo "Iteration $i: Failure"
fi
echo
echo "==========================="
echo "Successful runs: $success"
echo "Failed runs: $failure"
echo "==========================="
echo
done
echo "failure=$failure" >> $GITHUB_OUTPUT
- name: "Success and Failure Summary: ${{ inputs.os }}/Python ${{ inputs.python_version }}"
run: |
echo "Batch: ${{ matrix.batch }}"
echo "Successful runs: ${{ steps.pytest.outputs.success }}"
echo "Failed runs: ${{ steps.pytest.outputs.failure }}"
- name: "Error for Failures"
if: ${{ steps.pytest.outputs.failure }}
run: |
echo "Batch ${{ matrix.batch }} failed ${{ steps.pytest.outputs.failure }} of ${{ inputs.num_runs_per_batch }} tests"
exit 1

33
.github/workflows/triage-labels.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
# **what?**
# When the core team triages, we sometimes need more information from the issue creator. In
# those cases we remove the `triage` label and add the `awaiting_response` label. Once we
# recieve a response in the form of a comment, we want the `awaiting_response` label removed
# in favor of the `triage` label so we are aware that the issue needs action.
# **why?**
# To help with out team triage issue tracking
# **when?**
# This will run when a comment is added to an issue and that issue has to `awaiting_response` label.
name: Update Triage Label
on: issue_comment
defaults:
run:
shell: bash
permissions:
issues: write
jobs:
triage_label:
if: contains(github.event.issue.labels.*.name, 'awaiting_response')
runs-on: ubuntu-latest
steps:
- name: initial labeling
uses: andymckay/labeler@master
with:
add-labels: "triage"
remove-labels: "awaiting_response"

View File

@@ -1,18 +1,15 @@
# **what?**
# This workflow will take a version number and a dry run flag. With that
# This workflow will take the new version number to bump to. With that
# it will run versionbump to update the version number everywhere in the
# code base and then generate an update Docker requirements file. If this
# is a dry run, a draft PR will open with the changes. If this isn't a dry
# run, the changes will be committed to the branch this is run on.
# code base and then run changie to create the corresponding changelog.
# A PR will be created with the changes that can be reviewed before committing.
# **why?**
# This is to aid in releasing dbt and making sure we have updated
# the versions and Docker requirements in all places.
# the version in all places and generated the changelog.
# **when?**
# This is triggered either manually OR
# from the repository_dispatch event "version-bump" which is sent from
# the dbt-release repo Action
# This is triggered manually
name: Version Bump
@@ -20,90 +17,12 @@ on:
workflow_dispatch:
inputs:
version_number:
description: 'The version number to bump to'
description: 'The version number to bump to (ex. 1.2.0, 1.3.0b1)'
required: true
is_dry_run:
description: 'Creates a draft PR to allow testing instead of committing to a branch'
required: true
default: 'true'
repository_dispatch:
types: [version-bump]
jobs:
bump:
runs-on: ubuntu-latest
steps:
- name: Check out the repository
uses: actions/checkout@v2
- name: Set version and dry run values
id: variables
env:
VERSION_NUMBER: "${{ github.event.client_payload.version_number == '' && github.event.inputs.version_number || github.event.client_payload.version_number }}"
IS_DRY_RUN: "${{ github.event.client_payload.is_dry_run == '' && github.event.inputs.is_dry_run || github.event.client_payload.is_dry_run }}"
run: |
echo Repository dispatch event version: ${{ github.event.client_payload.version_number }}
echo Repository dispatch event dry run: ${{ github.event.client_payload.is_dry_run }}
echo Workflow dispatch event version: ${{ github.event.inputs.version_number }}
echo Workflow dispatch event dry run: ${{ github.event.inputs.is_dry_run }}
echo ::set-output name=VERSION_NUMBER::$VERSION_NUMBER
echo ::set-output name=IS_DRY_RUN::$IS_DRY_RUN
- uses: actions/setup-python@v2
with:
python-version: "3.8"
- name: Install python dependencies
run: |
python3 -m venv env
source env/bin/activate
pip install --upgrade pip
- name: Create PR branch
if: ${{ steps.variables.outputs.IS_DRY_RUN == 'true' }}
run: |
git checkout -b bumping-version/${{steps.variables.outputs.VERSION_NUMBER}}_$GITHUB_RUN_ID
git push origin bumping-version/${{steps.variables.outputs.VERSION_NUMBER}}_$GITHUB_RUN_ID
git branch --set-upstream-to=origin/bumping-version/${{steps.variables.outputs.VERSION_NUMBER}}_$GITHUB_RUN_ID bumping-version/${{steps.variables.outputs.VERSION_NUMBER}}_$GITHUB_RUN_ID
# - name: Generate Docker requirements
# run: |
# source env/bin/activate
# pip install -r requirements.txt
# pip freeze -l > docker/requirements/requirements.txt
# git status
- name: Bump version
run: |
source env/bin/activate
pip install -r dev-requirements.txt
env/bin/bumpversion --allow-dirty --new-version ${{steps.variables.outputs.VERSION_NUMBER}} major
git status
- name: Commit version bump directly
uses: EndBug/add-and-commit@v7
if: ${{ steps.variables.outputs.IS_DRY_RUN == 'false' }}
with:
author_name: 'Github Build Bot'
author_email: 'buildbot@fishtownanalytics.com'
message: 'Bumping version to ${{steps.variables.outputs.VERSION_NUMBER}}'
- name: Commit version bump to branch
uses: EndBug/add-and-commit@v7
if: ${{ steps.variables.outputs.IS_DRY_RUN == 'true' }}
with:
author_name: 'Github Build Bot'
author_email: 'buildbot@fishtownanalytics.com'
message: 'Bumping version to ${{steps.variables.outputs.VERSION_NUMBER}}'
branch: 'bumping-version/${{steps.variables.outputs.VERSION_NUMBER}}_${{GITHUB.RUN_ID}}'
push: 'origin origin/bumping-version/${{steps.variables.outputs.VERSION_NUMBER}}_${{GITHUB.RUN_ID}}'
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
if: ${{ steps.variables.outputs.IS_DRY_RUN == 'true' }}
with:
author: 'Github Build Bot <buildbot@fishtownanalytics.com>'
draft: true
base: ${{github.ref}}
title: 'Bumping version to ${{steps.variables.outputs.VERSION_NUMBER}}'
branch: 'bumping-version/${{steps.variables.outputs.VERSION_NUMBER}}_${{GITHUB.RUN_ID}}'
version_bump_and_changie:
uses: dbt-labs/actions/.github/workflows/version-bump.yml@main
with:
version_number: ${{ inputs.version_number }}
secrets: inherit # ok since what we are calling is internally maintained

9
.gitignore vendored
View File

@@ -11,6 +11,7 @@ __pycache__/
env*/
dbt_env/
build/
!core/dbt/docs/build
develop-eggs/
dist/
downloads/
@@ -24,7 +25,8 @@ var/
*.egg-info/
.installed.cfg
*.egg
*.mypy_cache/
.mypy_cache/
.dmypy.json
logs/
# PyInstaller
@@ -49,6 +51,7 @@ coverage.xml
*,cover
.hypothesis/
test.env
makefile.test.env
*.pytest_cache/
@@ -95,3 +98,7 @@ venv/
# vscode
.vscode/
*.code-workspace
# poetry
poetry.lock

View File

@@ -1,12 +1,11 @@
# Configuration for pre-commit hooks (see https://pre-commit.com/).
# Eventually the hooks described here will be run as tests before merging each PR.
# TODO: remove global exclusion of tests when testing overhaul is complete
exclude: ^test/
exclude: ^(core/dbt/docs/build/|core/dbt/events/types_pb2.py)
# Force all unspecified python hooks to run python 3.8
default_language_version:
python: python3.8
python: python3
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
@@ -21,21 +20,16 @@ repos:
- "markdown"
- id: check-case-conflict
- repo: https://github.com/psf/black
rev: 21.12b0
rev: 22.3.0
hooks:
- id: black
args:
- "--line-length=99"
- "--target-version=py38"
- id: black
alias: black-check
stages: [manual]
args:
- "--line-length=99"
- "--target-version=py38"
- "--check"
- "--diff"
- repo: https://gitlab.com/pycqa/flake8
- repo: https://github.com/pycqa/flake8
rev: 4.0.1
hooks:
- id: flake8
@@ -43,7 +37,7 @@ repos:
alias: flake8-check
stages: [manual]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.782
rev: v0.981
hooks:
- id: mypy
# N.B.: Mypy is... a bit fragile.

3765
CHANGELOG.md Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,79 +1,30 @@
# Contributing to `dbt`
# Contributing to `dbt-core`
`dbt-core` is open source software. It is what it is today because community members have opened issues, provided feedback, and [contributed to the knowledge loop](https://www.getdbt.com/dbt-labs/values/). Whether you are a seasoned open source contributor or a first-time committer, we welcome and encourage you to contribute code, documentation, ideas, or problem statements to this project.
1. [About this document](#about-this-document)
2. [Proposing a change](#proposing-a-change)
3. [Getting the code](#getting-the-code)
4. [Setting up an environment](#setting-up-an-environment)
5. [Running `dbt` in development](#running-dbt-in-development)
6. [Testing](#testing)
7. [Submitting a Pull Request](#submitting-a-pull-request)
2. [Getting the code](#getting-the-code)
3. [Setting up an environment](#setting-up-an-environment)
4. [Running `dbt` in development](#running-dbt-core-in-development)
5. [Testing dbt-core](#testing)
6. [Debugging](#debugging)
7. [Adding a changelog entry](#adding-a-changelog-entry)
8. [Submitting a Pull Request](#submitting-a-pull-request)
## About this document
This document is a guide intended for folks interested in contributing to `dbt-core`. Below, we document the process by which members of the community should create issues and submit pull requests (PRs) in this repository. It is not intended as a guide for using `dbt-core`, and it assumes a certain level of familiarity with Python concepts such as virtualenvs, `pip`, python modules, filesystems, and so on. This guide assumes you are using macOS or Linux and are comfortable with the command line.
There are many ways to contribute to the ongoing development of `dbt-core`, such as by participating in discussions and issues. We encourage you to first read our higher-level document: ["Expectations for Open Source Contributors"](https://docs.getdbt.com/docs/contributing/oss-expectations).
If you're new to python development or contributing to open-source software, we encourage you to read this document from start to finish. If you get stuck, drop us a line in the `#dbt-core-development` channel on [slack](https://community.getdbt.com).
The rest of this document serves as a more granular guide for contributing code changes to `dbt-core` (this repository). It is not intended as a guide for using `dbt-core`, and some pieces assume a level of familiarity with Python development (virtualenvs, `pip`, etc). Specific code snippets in this guide assume you are using macOS or Linux and are comfortable with the command line.
#### Adapters
If you get stuck, we're happy to help! Drop us a line in the `#dbt-core-development` channel in the [dbt Community Slack](https://community.getdbt.com).
If you have an issue or code change suggestion related to a specific database [adapter](https://docs.getdbt.com/docs/available-adapters); please refer to that supported databases seperate repo for those contributions.
### Notes
### Signing the CLA
Please note that all contributors to `dbt-core` must sign the [Contributor License Agreement](https://docs.getdbt.com/docs/contributor-license-agreements) to have their Pull Request merged into the `dbt-core` codebase. If you are unable to sign the CLA, then the `dbt-core` maintainers will unfortunately be unable to merge your Pull Request. You are, however, welcome to open issues and comment on existing ones.
## Proposing a change
`dbt-core` is Apache 2.0-licensed open source software. `dbt-core` is what it is today because community members like you have opened issues, provided feedback, and contributed to the knowledge loop for the entire communtiy. Whether you are a seasoned open source contributor or a first-time committer, we welcome and encourage you to contribute code, documentation, ideas, or problem statements to this project.
### Defining the problem
If you have an idea for a new feature or if you've discovered a bug in `dbt-core`, the first step is to open an issue. Please check the list of [open issues](https://github.com/dbt-labs/dbt-core/issues) before creating a new one. If you find a relevant issue, please add a comment to the open issue instead of creating a new one. There are hundreds of open issues in this repository and it can be hard to know where to look for a relevant open issue. **The `dbt-core` maintainers are always happy to point contributors in the right direction**, so please err on the side of documenting your idea in a new issue if you are unsure where a problem statement belongs.
> **Note:** All community-contributed Pull Requests _must_ be associated with an open issue. If you submit a Pull Request that does not pertain to an open issue, you will be asked to create an issue describing the problem before the Pull Request can be reviewed.
### Discussing the idea
After you open an issue, a `dbt-core` maintainer will follow up by commenting on your issue (usually within 1-3 days) to explore your idea further and advise on how to implement the suggested changes. In many cases, community members will chime in with their own thoughts on the problem statement. If you as the issue creator are interested in submitting a Pull Request to address the issue, you should indicate this in the body of the issue. The `dbt-core` maintainers are _always_ happy to help contributors with the implementation of fixes and features, so please also indicate if there's anything you're unsure about or could use guidance around in the issue.
### Submitting a change
If an issue is appropriately well scoped and describes a beneficial change to the `dbt-core` codebase, then anyone may submit a Pull Request to implement the functionality described in the issue. See the sections below on how to do this.
The `dbt-core` maintainers will add a `good first issue` label if an issue is suitable for a first-time contributor. This label often means that the required code change is small, limited to one database adapter, or a net-new addition that does not impact existing functionality. You can see the list of currently open issues on the [Contribute](https://github.com/dbt-labs/dbt-core/contribute) page.
Here's a good workflow:
- Comment on the open issue, expressing your interest in contributing the required code change
- Outline your planned implementation. If you want help getting started, ask!
- Follow the steps outlined below to develop locally. Once you have opened a PR, one of the `dbt-core` maintainers will work with you to review your code.
- Add a test! Tests are crucial for both fixes and new features alike. We want to make sure that code works as intended, and that it avoids any bugs previously encountered. Currently, the best resource for understanding `dbt-core`'s [unit](test/unit) and [integration](test/integration) tests is the tests themselves. One of the maintainers can help by pointing out relevant examples.
- Check your formatting and linting with [Flake8](https://flake8.pycqa.org/en/latest/#), [Black](https://github.com/psf/black), and the rest of the hooks we have in our [pre-commit](https://pre-commit.com/) [config](https://github.com/dbt-labs/dbt-core/blob/75201be9db1cb2c6c01fa7e71a314f5e5beb060a/.pre-commit-config.yaml).
In some cases, the right resolution to an open issue might be tangential to the `dbt-core` codebase. The right path forward might be a documentation update or a change that can be made in user-space. In other cases, the issue might describe functionality that the `dbt-core` maintainers are unwilling or unable to incorporate into the `dbt-core` codebase. When it is determined that an open issue describes functionality that will not translate to a code change in the `dbt-core` repository, the issue will be tagged with the `wontfix` label (see below) and closed.
### Using issue labels
The `dbt-core` maintainers use labels to categorize open issues. Most labels describe the domain in the `dbt-core` codebase germane to the discussion.
| tag | description |
| --- | ----------- |
| [triage](https://github.com/dbt-labs/dbt-core/labels/triage) | This is a new issue which has not yet been reviewed by a `dbt-core` maintainer. This label is removed when a maintainer reviews and responds to the issue. |
| [bug](https://github.com/dbt-labs/dbt-core/labels/bug) | This issue represents a defect or regression in `dbt-core` |
| [enhancement](https://github.com/dbt-labs/dbt-core/labels/enhancement) | This issue represents net-new functionality in `dbt-core` |
| [good first issue](https://github.com/dbt-labs/dbt-core/labels/good%20first%20issue) | This issue does not require deep knowledge of the `dbt-core` codebase to implement. This issue is appropriate for a first-time contributor. |
| [help wanted](https://github.com/dbt-labs/dbt-core/labels/help%20wanted) / [discussion](https://github.com/dbt-labs/dbt-core/labels/discussion) | Conversation around this issue in ongoing, and there isn't yet a clear path forward. Input from community members is most welcome. |
| [duplicate](https://github.com/dbt-labs/dbt-core/issues/duplicate) | This issue is functionally identical to another open issue. The `dbt-core` maintainers will close this issue and encourage community members to focus conversation on the other one. |
| [snoozed](https://github.com/dbt-labs/dbt-core/labels/snoozed) | This issue describes a good idea, but one which will probably not be addressed in a six-month time horizon. The `dbt-core` maintainers will revist these issues periodically and re-prioritize them accordingly. |
| [stale](https://github.com/dbt-labs/dbt-core/labels/stale) | This is an old issue which has not recently been updated. Stale issues will periodically be closed by `dbt-core` maintainers, but they can be re-opened if the discussion is restarted. |
| [wontfix](https://github.com/dbt-labs/dbt-core/labels/wontfix) | This issue does not require a code change in the `dbt-core` repository, or the maintainers are unwilling/unable to merge a Pull Request which implements the behavior described in the issue. |
#### Branching Strategy
`dbt-core` has three types of branches:
- **Trunks** are where active development of the next release takes place. There is one trunk named `main` at the time of writing this, and will be the default branch of the repository.
- **Release Branches** track a specific, not yet complete release of `dbt-core`. Each minor version release has a corresponding release branch. For example, the `0.11.x` series of releases has a branch called `0.11.latest`. This allows us to release new patch versions under `0.11` without necessarily needing to pull them into the latest version of `dbt-core`.
- **Feature Branches** track individual features and fixes. On completion they should be merged into the trunk branch or a specific release branch.
- **Adapters:** Is your issue or proposed code change related to a specific [database adapter](https://docs.getdbt.com/docs/available-adapters)? If so, please open issues, PRs, and discussions in that adapter's repository instead. The sole exception is Postgres; the `dbt-postgres` plugin lives in this repository (`dbt-core`).
- **CLA:** Please note that anyone contributing code to `dbt-core` must sign the [Contributor License Agreement](https://docs.getdbt.com/docs/contributor-license-agreements). If you are unable to sign the CLA, the `dbt-core` maintainers will unfortunately be unable to merge any of your Pull Requests. We welcome you to participate in discussions, open issues, and comment on existing ones.
- **Branches:** All pull requests from community contributors should target the `main` branch (default). If the change is needed as a patch for a minor version of dbt that has already been released (or is already a release candidate), a maintainer will backport the changes in your PR to the relevant "latest" release branch (`1.0.latest`, `1.1.latest`, ...). If an issue fix applies to a release branch, that fix should be first committed to the development branch and then to the release branch (rarely release-branch fixes may not apply to `main`).
- **Releases**: Before releasing a new minor version of Core, we prepare a series of alphas and release candidates to allow users (especially employees of dbt Labs!) to test the new version in live environments. This is an important quality assurance step, as it exposes the new code to a wide variety of complicated deployments and can surface bugs before official release. Releases are accessible via pip, homebrew, and dbt Cloud.
## Getting the code
@@ -85,15 +36,17 @@ You will need `git` in order to download and modify the `dbt-core` source code.
If you are not a member of the `dbt-labs` GitHub organization, you can contribute to `dbt-core` by forking the `dbt-core` repository. For a detailed overview on forking, check out the [GitHub docs on forking](https://help.github.com/en/articles/fork-a-repo). In short, you will need to:
1. fork the `dbt-core` repository
2. clone your fork locally
3. check out a new branch for your proposed changes
4. push changes to your fork
5. open a pull request against `dbt-labs/dbt` from your forked repository
1. Fork the `dbt-core` repository
2. Clone your fork locally
3. Check out a new branch for your proposed changes
4. Push changes to your fork
5. Open a pull request against `dbt-labs/dbt-core` from your forked repository
### dbt Labs contributors
If you are a member of the `dbt-labs` GitHub organization, you will have push access to the `dbt-core` repo. Rather than forking `dbt-core` to make your changes, just clone the repository, check out a new branch, and push directly to that branch.
If you are a member of the `dbt-labs` GitHub organization, you will have push access to the `dbt-core` repo. Rather than forking `dbt-core` to make your changes, just clone the repository, check out a new branch, and push directly to that branch. Branch names should be fixed by `CT-XXX/` where:
* CT stands for 'core team'
* XXX stands for a JIRA ticket number
## Setting up an environment
@@ -101,19 +54,21 @@ There are some tools that will be helpful to you in developing locally. While th
### Tools
A short list of tools used in `dbt-core` testing that will be helpful to your understanding:
These are the tools used in `dbt-core` development and testing:
- [`tox`](https://tox.readthedocs.io/en/latest/) to manage virtualenvs across python versions. We currently target the latest patch releases for Python 3.7, Python 3.8, and Python 3.9
- [`pytest`](https://docs.pytest.org/en/latest/) to discover/run tests
- [`make`](https://users.cs.duke.edu/~ola/courses/programming/Makefiles/Makefiles.html) - but don't worry too much, nobody _really_ understands how make works and our Makefile is super simple
- [`tox`](https://tox.readthedocs.io/en/latest/) to manage virtualenvs across python versions. We currently target the latest patch releases for Python 3.7, 3.8, 3.9, 3.10 and 3.11
- [`pytest`](https://docs.pytest.org/en/latest/) to define, discover, and run tests
- [`flake8`](https://flake8.pycqa.org/en/latest/) for code linting
- [`black`](https://github.com/psf/black) for code formatting
- [`mypy`](https://mypy.readthedocs.io/en/stable/) for static type checking
- [Github Actions](https://github.com/features/actions)
- [`pre-commit`](https://pre-commit.com) to easily run those checks
- [`changie`](https://changie.dev/) to create changelog entries, without merge conflicts
- [`make`](https://users.cs.duke.edu/~ola/courses/programming/Makefiles/Makefiles.html) to run multiple setup or test steps in combination. Don't worry too much, nobody _really_ understands how `make` works, and our Makefile aims to be super simple.
- [GitHub Actions](https://github.com/features/actions) for automating tests and checks, once a PR is pushed to the `dbt-core` repository
A deep understanding of these tools in not required to effectively contribute to `dbt-core`, but we recommend checking out the attached documentation if you're interested in learning more about them.
A deep understanding of these tools in not required to effectively contribute to `dbt-core`, but we recommend checking out the attached documentation if you're interested in learning more about each one.
#### virtual environments
#### Virtual environments
We strongly recommend using virtual environments when developing code in `dbt-core`. We recommend creating this virtualenv
in the root of the `dbt-core` repository. To create a new virtualenv, run:
@@ -124,12 +79,12 @@ source env/bin/activate
This will create and activate a new Python virtual environment.
#### docker and docker-compose
#### Docker and `docker-compose`
Docker and docker-compose are both used in testing. Specific instructions for you OS can be found [here](https://docs.docker.com/get-docker/).
Docker and `docker-compose` are both used in testing. Specific instructions for you OS can be found [here](https://docs.docker.com/get-docker/).
#### postgres (optional)
#### Postgres (optional)
For testing, and later in the examples in this document, you may want to have `psql` available so you can poke around in the database and see what happened. We recommend that you use [homebrew](https://brew.sh/) for that on macOS, and your package manager on Linux. You can install any version of the postgres client that you'd like. On macOS, with homebrew setup, you can run:
@@ -141,32 +96,37 @@ brew install postgresql
### 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) with:
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):
```sh
make dev
# or
```
or, alternatively:
```sh
pip install -r dev-requirements.txt -r editable-requirements.txt
pre-commit install
```
When `dbt-core` is installed this way, any changes you make to the `dbt-core` source code will be reflected immediately in your next `dbt-core` 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.
### Running `dbt-core`
With your virtualenv activated, the `dbt-core` script should point back to the source code you've cloned on your machine. You can verify this by running `which dbt`. This command should show you a path to an executable in your virtualenv.
With your virtualenv activated, the `dbt` script should point back to the source code you've cloned on your machine. You can verify this by running `which dbt`. This command should show you a path to an executable in your virtualenv.
Configure your [profile](https://docs.getdbt.com/docs/configure-your-profile) as necessary to connect to your target databases. It may be a good idea to add a new profile pointing to a local postgres instance, or a specific test sandbox within your data warehouse if appropriate.
Configure your [profile](https://docs.getdbt.com/docs/configure-your-profile) as necessary to connect to your target databases. It may be a good idea to add a new profile pointing to a local Postgres instance, or a specific test sandbox within your data warehouse if appropriate.
## Testing
Getting the `dbt-core` integration tests set up in your local environment will be very helpful as you start to make changes to your local version of `dbt-core`. The section that follows outlines some helpful tips for setting up the test environment.
Once you're able to manually test that your code change is working as expected, it's important to run existing automated tests, as well as adding some new ones. These tests will ensure that:
- Your code changes do not unexpectedly break other established functionality
- Your code changes can handle all known edge cases
- The functionality you're adding will _keep_ working in the future
Although `dbt-core` works with a number of different databases, you won't need to supply credentials for every one of these databases in your test environment. Instead you can test all dbt-core code changes with Python and Postgres.
Although `dbt-core` works with a number of different databases, you won't need to supply credentials for every one of these databases in your test environment. Instead, you can test most `dbt-core` code changes with Python and Postgres.
### Initial setup
We recommend starting with `dbt-core`'s Postgres tests. These tests cover most of the functionality in `dbt-core`, are the fastest to run, and are the easiest to set up. To run the Postgres integration tests, you'll have to do one extra step of setting up the test database:
Postgres offers the easiest way to test most `dbt-core` functionality today. They are the fastest to run, and the easiest to set up. To run the Postgres integration tests, you'll have to do one extra step of setting up the test database:
```sh
make setup-db
@@ -192,39 +152,82 @@ make test
# Runs postgres integration tests with py38 in "fail fast" mode.
make integration
```
> These make targets assume you have a local install of a recent version of [`tox`](https://tox.readthedocs.io/en/latest/) for unit/integration testing and pre-commit for code quality checks,
> These make targets assume you have a local installation of a recent version of [`tox`](https://tox.readthedocs.io/en/latest/) for unit/integration testing and pre-commit for code quality checks,
> unless you use choose a Docker container to run tests. Run `make help` for more info.
Check out the other targets in the Makefile to see other commonly used test
suites.
#### `pre-commit`
[`pre-commit`](https.pre-commit.com) takes care of running all code-checks for formatting and linting. Run `make dev` to install `pre-commit` in your local environment. Once this is done you can use any of the linter-based make targets as well as a git pre-commit hook that will ensure proper formatting and linting.
[`pre-commit`](https://pre-commit.com) takes care of running all code-checks for formatting and linting. Run `make dev` to install `pre-commit` in your local environment (we recommend running this command with a python virtual environment active). This command installs several pip executables including black, mypy, and flake8. Once this is done you can use any of the linter-based make targets as well as a git pre-commit hook that will ensure proper formatting and linting.
#### `tox`
[`tox`](https://tox.readthedocs.io/en/latest/) takes care of managing virtualenvs and install dependencies in order to run tests. You can also run tests in parallel, for example, you can run unit tests for Python 3.7, Python 3.8, and Python 3.9 checks in parallel with `tox -p`. Also, you can run unit tests for specific python versions with `tox -e py37`. The configuration for these tests in located in `tox.ini`.
[`tox`](https://tox.readthedocs.io/en/latest/) takes care of managing virtualenvs and install dependencies in order to run tests. You can also run tests in parallel, for example, you can run unit tests for Python 3.7, Python 3.8, Python 3.9, Python 3.10 and Python 3.11 checks in parallel with `tox -p`. Also, you can run unit tests for specific python versions with `tox -e py37`. The configuration for these tests in located in `tox.ini`.
#### `pytest`
Finally, you can also run a specific test or group of tests using [`pytest`](https://docs.pytest.org/en/latest/) directly. With a virtualenv
active and dev dependencies installed you can do things like:
Finally, you can also run a specific test or group of tests using [`pytest`](https://docs.pytest.org/en/latest/) directly. With a virtualenv active and dev dependencies installed you can do things like:
```sh
# run specific postgres integration tests
python -m pytest -m profile_postgres test/integration/001_simple_copy_test
# run all unit tests in a file
python -m pytest test/unit/test_graph.py
python3 -m pytest test/unit/test_graph.py
# run a specific unit test
python -m pytest test/unit/test_graph.py::GraphTest::test__dependency_list
python3 -m pytest test/unit/test_graph.py::GraphTest::test__dependency_list
# run specific Postgres integration tests (old way)
python3 -m pytest -m profile_postgres test/integration/074_postgres_unlogged_table_tests
# run specific Postgres integration tests (new way)
python3 -m pytest tests/functional/sources
```
> [Here](https://docs.pytest.org/en/reorganize-docs/new-docs/user/commandlineuseful.html)
> is a list of useful command-line options for `pytest` to use while developing.
> See [pytest usage docs](https://docs.pytest.org/en/6.2.x/usage.html) for an overview of useful command-line options.
### Unit, Integration, Functional?
Here are some general rules for adding tests:
* unit tests (`test/unit` & `tests/unit`) dont need to access a database; "pure Python" tests should be written as unit tests
* functional tests (`test/integration` & `tests/functional`) cover anything that interacts with a database, namely adapter
* *everything in* `test/*` *is being steadily migrated to* `tests/*`
## Debugging
1. The logs for a `dbt run` have stack traces and other information for debugging errors (in `logs/dbt.log` in your project directory).
2. Try using a debugger, like `ipdb`. For pytest: `--pdb --pdbcls=IPython.terminal.debugger:pdb`
3. Sometimes, its easier to debug on a single thread: `dbt --single-threaded run`
4. To make print statements from Jinja macros: `{{ log(msg, info=true) }}`
5. You can also add `{{ debug() }}` statements, which will drop you into some auto-generated code that the macro wrote.
6. The dbt “artifacts” are written out to the target directory of your dbt project. They are in unformatted json, which can be hard to read. Format them with:
> python -m json.tool target/run_results.json > run_results.json
### Assorted development tips
* Append `# type: ignore` to the end of a line if you need to disable `mypy` on that line.
* Sometimes flake8 complains about lines that are actually fine, in which case you can put a comment on the line such as: # noqa or # noqa: ANNN, where ANNN is the error code that flake8 issues.
* To collect output for `CProfile`, run dbt with the `-r` option and the name of an output file, i.e. `dbt -r dbt.cprof run`. If you just want to profile parsing, you can do: `dbt -r dbt.cprof parse`. `pip` install `snakeviz` to view the output. Run `snakeviz dbt.cprof` and output will be rendered in a browser window.
## Adding or modifying a CHANGELOG Entry
We use [changie](https://changie.dev) to generate `CHANGELOG` entries. **Note:** Do not edit the `CHANGELOG.md` directly. Your modifications will be lost.
Follow the steps to [install `changie`](https://changie.dev/guide/installation/) for your system.
Once changie is installed and your PR is created for a new feature, simply run the following command and changie will walk you through the process of creating a changelog entry:
```shell
changie new
```
Commit the file that's created and your changelog entry is complete!
If you are contributing to a feature already in progress, you will modify the changie yaml file in dbt/.changes/unreleased/ related to your change. If you need help finding this file, please ask within the discussion for the pull request!
You don't need to worry about which `dbt-core` version your change will go into. Just create the changelog entry with `changie`, and open your PR against the `main` branch. All merged changes will be included in the next minor version of `dbt-core`. The Core maintainers _may_ choose to "backport" specific changes in order to patch older minor versions. In that case, a maintainer will take care of that backport after merging your PR, before releasing the new version of `dbt-core`.
## Submitting a Pull Request
dbt Labs provides a CI environment to test changes to specific adapters, and periodic maintenance checks of `dbt-core` through Github Actions. For example, if you submit a pull request to the `dbt-redshift` repo, GitHub will trigger automated code checks and tests against Redshift.
A `dbt-core` maintainer will review your PR. They may suggest code revision for style or clarity, or request that you add unit or integration test(s). These are good things! We believe that, with a little bit of help, anyone can contribute high-quality code.
- First time contributors should note code checks + unit tests require a maintainer to approve.
Code can be merged into the current development branch `main` by opening a pull request. A `dbt-core` maintainer will review your PR. They may suggest code revision for style or clarity, or request that you add unit or integration test(s). These are good things! We believe that, with a little bit of help, anyone can contribute high-quality code.
Automated tests run via GitHub Actions. If you're a first-time contributor, all tests (including code checks and unit tests) will require a maintainer to approve. Changes in the `dbt-core` repository trigger integration tests against Postgres. dbt Labs also provides CI environments in which to test changes to other adapters, triggered by PRs in those adapters' repositories, as well as periodic maintenance checks of each adapter in concert with the latest `dbt-core` code changes.
Once all tests are passing and your PR has been approved, a `dbt-core` maintainer will merge your changes into the active development branch. And that's it! Happy developing :tada:
Sometimes, the content license agreement auto-check bot doesn't find a user's entry in its roster. If you need to force a rerun, add `@cla-bot check` in a comment on the pull request.

View File

@@ -3,7 +3,7 @@
# See `/docker` for a generic and production-ready docker file
##
FROM ubuntu:20.04
FROM ubuntu:23.04
ENV DEBIAN_FRONTEND noninteractive
@@ -46,6 +46,12 @@ RUN apt-get update \
python3.9 \
python3.9-dev \
python3.9-venv \
python3.10 \
python3.10-dev \
python3.10-venv \
python3.11 \
python3.11-dev \
python3.11-venv \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

View File

@@ -6,12 +6,42 @@ ifeq ($(USE_DOCKER),true)
DOCKER_CMD := docker-compose run --rm test
endif
.PHONY: dev
dev: ## Installs dbt-* packages in develop mode along with development dependencies.
#
# To override CI_flags, create a file at this repo's root dir named `makefile.test.env`. Fill it
# with any ENV_VAR overrides required by your test environment, e.g.
# DBT_TEST_USER_1=user
# LOG_DIR="dir with a space in it"
#
# Warn: Restrict each line to one variable only.
#
ifeq (./makefile.test.env,$(wildcard ./makefile.test.env))
include ./makefile.test.env
endif
CI_FLAGS =\
DBT_TEST_USER_1=$(if $(DBT_TEST_USER_1),$(DBT_TEST_USER_1),dbt_test_user_1)\
DBT_TEST_USER_2=$(if $(DBT_TEST_USER_2),$(DBT_TEST_USER_2),dbt_test_user_2)\
DBT_TEST_USER_3=$(if $(DBT_TEST_USER_3),$(DBT_TEST_USER_3),dbt_test_user_3)\
RUSTFLAGS=$(if $(RUSTFLAGS),$(RUSTFLAGS),"-D warnings")\
LOG_DIR=$(if $(LOG_DIR),$(LOG_DIR),./logs)\
DBT_LOG_FORMAT=$(if $(DBT_LOG_FORMAT),$(DBT_LOG_FORMAT),json)
.PHONY: dev_req
dev_req: ## Installs dbt-* packages in develop mode along with only development dependencies.
@\
pip install -r dev-requirements.txt
pip install -r editable-requirements.txt
.PHONY: dev
dev: dev_req ## Installs dbt-* packages in develop mode along with development dependencies and pre-commit.
@\
pip install -r dev-requirements.txt -r editable-requirements.txt && \
pre-commit install
.PHONY: proto_types
proto_types: ## generates google protobuf python file from types.proto
protoc -I=./core/dbt/events --python_out=./core/dbt/events ./core/dbt/events/types.proto
.PHONY: mypy
mypy: .env ## Runs mypy against staged changes for static type checking.
@\
@@ -34,33 +64,34 @@ lint: .env ## Runs flake8 and mypy code checks against staged changes.
$(DOCKER_CMD) pre-commit run mypy-check --hook-stage manual | grep -v "INFO"
.PHONY: unit
unit: .env ## Runs unit tests with py38.
unit: .env ## Runs unit tests with py
@\
$(DOCKER_CMD) tox -e py38
$(DOCKER_CMD) tox -e py
.PHONY: test
test: .env ## Runs unit tests with py38 and code checks against staged changes.
test: .env ## Runs unit tests with py and code checks against staged changes.
@\
$(DOCKER_CMD) tox -p -e py38; \
$(DOCKER_CMD) tox -e py; \
$(DOCKER_CMD) pre-commit run black-check --hook-stage manual | grep -v "INFO"; \
$(DOCKER_CMD) pre-commit run flake8-check --hook-stage manual | grep -v "INFO"; \
$(DOCKER_CMD) pre-commit run mypy-check --hook-stage manual | grep -v "INFO"
.PHONY: integration
integration: .env integration-postgres ## Alias for integration-postgres.
integration: .env ## Runs postgres integration tests with py-integration
@\
$(CI_FLAGS) $(DOCKER_CMD) tox -e py-integration -- -nauto
.PHONY: integration-fail-fast
integration-fail-fast: .env integration-postgres-fail-fast ## Alias for integration-postgres-fail-fast.
.PHONY: integration-postgres
integration-postgres: .env ## Runs postgres integration tests with py38.
integration-fail-fast: .env ## Runs postgres integration tests with py-integration in "fail fast" mode.
@\
$(DOCKER_CMD) tox -e py38-postgres -- -nauto
$(DOCKER_CMD) tox -e py-integration -- -x -nauto
.PHONY: integration-postgres-fail-fast
integration-postgres-fail-fast: .env ## Runs postgres integration tests with py38 in "fail fast" mode.
.PHONY: interop
interop: clean
@\
$(DOCKER_CMD) tox -e py38-postgres -- -x -nauto
mkdir $(LOG_DIR) && \
$(CI_FLAGS) $(DOCKER_CMD) tox -e py-integration -- -nauto && \
LOG_DIR=$(LOG_DIR) cargo run --manifest-path test/interop/log_parsing/Cargo.toml
.PHONY: setup-db
setup-db: ## Setup Postgres database with docker-compose for system testing.
@@ -83,6 +114,7 @@ endif
clean: ## Resets development environment.
@echo 'cleaning repo...'
@rm -f .coverage
@rm -f .coverage.*
@rm -rf .eggs/
@rm -f .env
@rm -rf .tox/

View File

@@ -3,16 +3,13 @@
</p>
<p align="center">
<a href="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml">
<img src="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml/badge.svg?event=push" alt="Unit Tests Badge"/>
</a>
<a href="https://github.com/dbt-labs/dbt-core/actions/workflows/integration.yml">
<img src="https://github.com/dbt-labs/dbt-core/actions/workflows/integration.yml/badge.svg?event=push" alt="Integration Tests Badge"/>
<img src="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml/badge.svg?event=push" alt="CI Badge"/>
</a>
</p>
**[dbt](https://www.getdbt.com/)** enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications.
![architecture](https://raw.githubusercontent.com/dbt-labs/dbt-core/6c6649f9129d5d108aa3b0526f634cd8f3a9d1ed/etc/dbt-arch.png)
![architecture](https://github.com/dbt-labs/dbt-core/blob/202cb7e51e218c7b29eb3b11ad058bd56b7739de/etc/dbt-transform.png)
## Understanding dbt
@@ -24,7 +21,7 @@ These select statements, or "models", form a dbt project. Models frequently buil
## Getting started
- [Install dbt](https://docs.getdbt.com/docs/installation)
- [Install dbt](https://docs.getdbt.com/docs/get-started/installation)
- Read the [introduction](https://docs.getdbt.com/docs/introduction/) and [viewpoint](https://docs.getdbt.com/docs/about/viewpoint/)
## Join the dbt Community

View File

@@ -1 +1,2 @@
recursive-include dbt/include *.py *.sql *.yml *.html *.md .gitkeep .gitignore
include dbt/py.typed

View File

@@ -3,10 +3,7 @@
</p>
<p align="center">
<a href="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml">
<img src="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml/badge.svg?event=push" alt="Unit Tests Badge"/>
</a>
<a href="https://github.com/dbt-labs/dbt-core/actions/workflows/integration.yml">
<img src="https://github.com/dbt-labs/dbt-core/actions/workflows/integration.yml/badge.svg?event=push" alt="Integration Tests Badge"/>
<img src="https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml/badge.svg?event=push" alt="CI Badge"/>
</a>
</p>

View File

@@ -2,50 +2,59 @@
## The following are individual files in this directory.
### deprecations.py
### flags.py
### main.py
### tracking.py
### version.py
### lib.py
### node_types.py
### helper_types.py
### links.py
### semver.py
### ui.py
### compilation.py
### constants.py
### dataclass_schema.py
### deprecations.py
### exceptions.py
### flags.py
### helper_types.py
### hooks.py
### lib.py
### links.py
### logger.py
### main.py
### node_types.py
### profiler.py
### selected_resources.py
### semver.py
### tracking.py
### ui.py
### utils.py
### version.py
## The subdirectories will be documented in a README in the subdirectory
* config
* include
* adapters
* context
* deps
* graph
* task
* cli
* clients
* config
* context
* contracts
* deps
* docs
* events
* graph
* include
* parser
* task
* tests

7
core/dbt/__init__.py Normal file
View File

@@ -0,0 +1,7 @@
# N.B.
# This will add to the packages __path__ all subdirectories of directories on sys.path named after the package which effectively combines both modules into a single namespace (dbt.adapters)
# The matching statement is in plugins/postgres/dbt/__init__.py
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

View File

@@ -1 +1,30 @@
# Adapters README
The Adapters module is responsible for defining database connection methods, caching information from databases, how relations are defined, and the two major connection types we have - base and sql.
# Directories
## `base`
Defines the base implementation Adapters can use to build out full functionality.
## `sql`
Defines a sql implementation for adapters that initially inherits the above base implementation and comes with some premade methods and macros that can be overwritten as needed per adapter. (most common type of adapter.)
# Files
## `cache.py`
Cached information from the database.
## `factory.py`
Defines how we generate adapter objects
## `protocol.py`
Defines various interfaces for various adapter objects. Helps mypy correctly resolve methods.
## `reference_keys.py`
Configures naming scheme for cache elements to be universal.

View File

@@ -0,0 +1,7 @@
# N.B.
# This will add to the packages __path__ all subdirectories of directories on sys.path named after the package which effectively combines both modules into a single namespace (dbt.adapters)
# The matching statement is in plugins/postgres/dbt/adapters/__init__.py
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

View File

@@ -0,0 +1,10 @@
## Base adapters
### impl.py
The class `SQLAdapter` in [base/imply.py](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/adapters/base/impl.py) is a (mostly) abstract object that adapter objects inherit from. The base class scaffolds out methods that every adapter project usually should implement for smooth communication between dbt and database.
Some target databases require more or fewer methods--it all depends on what the warehouse's featureset is.
Look into the class for function-level comments.

View File

@@ -1,14 +1,19 @@
# these are all just exports, #noqa them so flake8 will be happy
# TODO: Should we still include this in the `adapters` namespace?
from dbt.contracts.connection import Credentials # noqa
from dbt.adapters.base.meta import available # noqa
from dbt.adapters.base.connections import BaseConnectionManager # noqa
from dbt.adapters.base.relation import ( # noqa
from dbt.contracts.connection import Credentials # noqa: F401
from dbt.adapters.base.meta import available # noqa: F401
from dbt.adapters.base.connections import BaseConnectionManager # noqa: F401
from dbt.adapters.base.relation import ( # noqa: F401
BaseRelation,
RelationType,
SchemaSearchMap,
)
from dbt.adapters.base.column import Column # noqa
from dbt.adapters.base.impl import AdapterConfig, BaseAdapter # noqa
from dbt.adapters.base.plugin import AdapterPlugin # noqa
from dbt.adapters.base.column import Column # noqa: F401
from dbt.adapters.base.impl import ( # noqa: F401
AdapterConfig,
BaseAdapter,
PythonJobHelper,
ConstraintSupport,
)
from dbt.adapters.base.plugin import AdapterPlugin # noqa: F401

View File

@@ -2,7 +2,7 @@ from dataclasses import dataclass
import re
from typing import Dict, ClassVar, Any, Optional
from dbt.exceptions import RuntimeException
from dbt.exceptions import DbtRuntimeError
@dataclass
@@ -12,6 +12,7 @@ class Column:
"TIMESTAMP": "TIMESTAMP",
"FLOAT": "FLOAT",
"INTEGER": "INT",
"BOOLEAN": "BOOLEAN",
}
column: str
dtype: str
@@ -59,6 +60,7 @@ class Column:
"float",
"double precision",
"float8",
"double",
]
def is_integer(self) -> bool:
@@ -84,7 +86,7 @@ class Column:
def string_size(self) -> int:
if not self.is_string():
raise RuntimeException("Called string_size() on non-string field!")
raise DbtRuntimeError("Called string_size() on non-string field!")
if self.dtype == "text" or self.char_size is None:
# char_size should never be None. Handle it reasonably just in case
@@ -123,7 +125,7 @@ class Column:
def from_description(cls, name: str, raw_data_type: str) -> "Column":
match = re.match(r"([^(]+)(\([^)]+\))?", raw_data_type)
if match is None:
raise RuntimeException(f'Could not interpret data type "{raw_data_type}"')
raise DbtRuntimeError(f'Could not interpret data type "{raw_data_type}"')
data_type, size_info = match.groups()
char_size = None
numeric_precision = None
@@ -136,7 +138,7 @@ class Column:
try:
char_size = int(parts[0])
except ValueError:
raise RuntimeException(
raise DbtRuntimeError(
f'Could not interpret data_type "{raw_data_type}": '
f'could not convert "{parts[0]}" to an integer'
)
@@ -144,14 +146,14 @@ class Column:
try:
numeric_precision = int(parts[0])
except ValueError:
raise RuntimeException(
raise DbtRuntimeError(
f'Could not interpret data_type "{raw_data_type}": '
f'could not convert "{parts[0]}" to an integer'
)
try:
numeric_scale = int(parts[1])
except ValueError:
raise RuntimeException(
raise DbtRuntimeError(
f'Could not interpret data_type "{raw_data_type}": '
f'could not convert "{parts[1]}" to an integer'
)

View File

@@ -1,10 +1,25 @@
import abc
import os
from time import sleep
import sys
import traceback
# multiprocessing.RLock is a function returning this type
from multiprocessing.synchronize import RLock
from threading import get_ident
from typing import Dict, Tuple, Hashable, Optional, ContextManager, List, Union
from typing import (
Any,
Dict,
Tuple,
Hashable,
Optional,
ContextManager,
List,
Type,
Union,
Iterable,
Callable,
)
import agate
@@ -21,18 +36,24 @@ from dbt.contracts.graph.manifest import Manifest
from dbt.adapters.base.query_headers import (
MacroQueryStringSetter,
)
from dbt.events import AdapterLogger
from dbt.events.functions import fire_event
from dbt.events.types import (
NewConnection,
ConnectionReused,
ConnectionLeftOpenInCleanup,
ConnectionLeftOpen,
ConnectionLeftOpen2,
ConnectionClosedInCleanup,
ConnectionClosed,
ConnectionClosed2,
Rollback,
RollbackFailed,
)
from dbt.events.contextvars import get_node_info
from dbt import flags
from dbt.utils import cast_to_str
SleepTime = Union[int, float] # As taken by time.sleep.
AdapterHandle = Any # Adapter connection handle objects can be any class.
class BaseConnectionManager(metaclass=abc.ABCMeta):
@@ -70,13 +91,13 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
key = self.get_thread_identifier()
with self.lock:
if key not in self.thread_connections:
raise dbt.exceptions.InvalidConnectionException(key, list(self.thread_connections))
raise dbt.exceptions.InvalidConnectionError(key, list(self.thread_connections))
return self.thread_connections[key]
def set_thread_connection(self, conn: Connection) -> None:
key = self.get_thread_identifier()
if key in self.thread_connections:
raise dbt.exceptions.InternalException(
raise dbt.exceptions.DbtInternalError(
"In set_thread_connection, existing connection exists for {}"
)
self.thread_connections[key] = conn
@@ -116,57 +137,148 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
:return: A context manager that handles exceptions raised by the
underlying database.
"""
raise dbt.exceptions.NotImplementedException(
raise dbt.exceptions.NotImplementedError(
"`exception_handler` is not implemented for this adapter!"
)
def set_connection_name(self, name: Optional[str] = None) -> Connection:
conn_name: str
if name is None:
# if a name isn't specified, we'll re-use a single handle
# 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
"""Called by 'acquire_connection' in BaseAdapter, which is called by
'connection_named', called by 'connection_for(node)'.
Creates a connection for this thread if one doesn't already
exist, and will rename an existing connection."""
conn_name: str = "master" if name is None else name
# Get a connection for this thread
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:
# Create a new connection
conn = Connection(
type=Identifier(self.TYPE),
name=None,
name=conn_name,
state=ConnectionState.INIT,
transaction_open=False,
handle=None,
credentials=self.profile.credentials,
)
self.set_thread_connection(conn)
if conn.name == conn_name and conn.state == "open":
return conn
fire_event(NewConnection(conn_name=conn_name, conn_type=self.TYPE))
if conn.state == "open":
fire_event(ConnectionReused(conn_name=conn_name))
else:
conn.handle = LazyHandle(self.open)
# Add the connection to thread_connections for this thread
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))
conn.name = conn_name
return conn
@classmethod
def retry_connection(
cls,
connection: Connection,
connect: Callable[[], AdapterHandle],
logger: AdapterLogger,
retryable_exceptions: Iterable[Type[Exception]],
retry_limit: int = 1,
retry_timeout: Union[Callable[[int], SleepTime], SleepTime] = 1,
_attempts: int = 0,
) -> Connection:
"""Given a Connection, set its handle by calling connect.
The calls to connect will be retried up to retry_limit times to deal with transient
connection errors. By default, one retry will be attempted if retryable_exceptions is set.
:param Connection connection: An instance of a Connection that needs a handle to be set,
usually when attempting to open it.
:param connect: A callable that returns the appropiate connection handle for a
given adapter. This callable will be retried retry_limit times if a subclass of any
Exception in retryable_exceptions is raised by connect.
:type connect: Callable[[], AdapterHandle]
:param AdapterLogger logger: A logger to emit messages on retry attempts or errors. When
handling expected errors, we call debug, and call warning on unexpected errors or when
all retry attempts have been exhausted.
:param retryable_exceptions: An iterable of exception classes that if raised by
connect should trigger a retry.
:type retryable_exceptions: Iterable[Type[Exception]]
: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.
Must be non-negative.
: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
or float to be passed to time.sleep.
:type retry_timeout: Union[Callable[[int], SleepTime], SleepTime] = 1
: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
is a Callable. This parameter should not be set by the initial caller.
:raises dbt.exceptions.FailedToConnectError: Upon exhausting all retry attempts without
successfully acquiring a handle.
:return: The given connection with its appropriate state and handle attributes set
depending on whether we successfully acquired a handle or not.
"""
timeout = retry_timeout(_attempts) if callable(retry_timeout) else retry_timeout
if timeout < 0:
raise dbt.exceptions.FailedToConnectError(
"retry_timeout cannot be negative or return a negative time."
)
if retry_limit < 0 or retry_limit > sys.getrecursionlimit():
# This guard is not perfect others may add to the recursion limit (e.g. built-ins).
connection.handle = None
connection.state = ConnectionState.FAIL
raise dbt.exceptions.FailedToConnectError("retry_limit cannot be negative")
try:
connection.handle = connect()
connection.state = ConnectionState.OPEN
return connection
except tuple(retryable_exceptions) as e:
if retry_limit <= 0:
connection.handle = None
connection.state = ConnectionState.FAIL
raise dbt.exceptions.FailedToConnectError(str(e))
logger.debug(
f"Got a retryable error when attempting to open a {cls.TYPE} connection.\n"
f"{retry_limit} attempts remaining. Retrying in {timeout} seconds.\n"
f"Error:\n{e}"
)
sleep(timeout)
return cls.retry_connection(
connection=connection,
connect=connect,
logger=logger,
retry_limit=retry_limit - 1,
retry_timeout=retry_timeout,
retryable_exceptions=retryable_exceptions,
_attempts=_attempts + 1,
)
except Exception as e:
connection.handle = None
connection.state = ConnectionState.FAIL
raise dbt.exceptions.FailedToConnectError(str(e))
@abc.abstractmethod
def cancel_open(self) -> Optional[List[str]]:
"""Cancel all open connections on the adapter. (passable)"""
raise dbt.exceptions.NotImplementedException(
raise dbt.exceptions.NotImplementedError(
"`cancel_open` is not implemented for this adapter!"
)
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def open(cls, connection: Connection) -> Connection:
"""Open the given connection on the adapter and return it.
@@ -176,7 +288,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
This should be thread-safe, or hold the lock if necessary. The given
connection should not be in either in_use or available.
"""
raise dbt.exceptions.NotImplementedException("`open` is not implemented for this adapter!")
raise dbt.exceptions.NotImplementedError("`open` is not implemented for this adapter!")
def release(self) -> None:
with self.lock:
@@ -197,9 +309,9 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
with self.lock:
for connection in self.thread_connections.values():
if connection.state not in {"closed", "init"}:
fire_event(ConnectionLeftOpen(conn_name=connection.name))
fire_event(ConnectionLeftOpenInCleanup(conn_name=cast_to_str(connection.name)))
else:
fire_event(ConnectionClosed(conn_name=connection.name))
fire_event(ConnectionClosedInCleanup(conn_name=cast_to_str(connection.name)))
self.close(connection)
# garbage collect these connections
@@ -208,16 +320,12 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
@abc.abstractmethod
def begin(self) -> None:
"""Begin a transaction. (passable)"""
raise dbt.exceptions.NotImplementedException(
"`begin` is not implemented for this adapter!"
)
raise dbt.exceptions.NotImplementedError("`begin` is not implemented for this adapter!")
@abc.abstractmethod
def commit(self) -> None:
"""Commit a transaction. (passable)"""
raise dbt.exceptions.NotImplementedException(
"`commit` is not implemented for this adapter!"
)
raise dbt.exceptions.NotImplementedError("`commit` is not implemented for this adapter!")
@classmethod
def _rollback_handle(cls, connection: Connection) -> None:
@@ -225,28 +333,40 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
try:
connection.handle.rollback()
except Exception:
fire_event(RollbackFailed(conn_name=connection.name))
fire_event(
RollbackFailed(
conn_name=cast_to_str(connection.name),
exc_info=traceback.format_exc(),
node_info=get_node_info(),
)
)
@classmethod
def _close_handle(cls, connection: Connection) -> None:
"""Perform the actual close operation."""
# On windows, sometimes connection handles don't have a close() attr.
if hasattr(connection.handle, "close"):
fire_event(ConnectionClosed2(conn_name=connection.name))
fire_event(
ConnectionClosed(conn_name=cast_to_str(connection.name), node_info=get_node_info())
)
connection.handle.close()
else:
fire_event(ConnectionLeftOpen2(conn_name=connection.name))
fire_event(
ConnectionLeftOpen(
conn_name=cast_to_str(connection.name), node_info=get_node_info()
)
)
@classmethod
def _rollback(cls, connection: Connection) -> None:
"""Roll back the given connection."""
if connection.transaction_open is False:
raise dbt.exceptions.InternalException(
raise dbt.exceptions.DbtInternalError(
f"Tried to rollback transaction on connection "
f'"{connection.name}", but it does not have one open!'
)
fire_event(Rollback(conn_name=connection.name))
fire_event(Rollback(conn_name=cast_to_str(connection.name), node_info=get_node_info()))
cls._rollback_handle(connection)
connection.transaction_open = False
@@ -258,7 +378,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
return connection
if connection.transaction_open and connection.handle:
fire_event(Rollback(conn_name=connection.name))
fire_event(Rollback(conn_name=cast_to_str(connection.name), node_info=get_node_info()))
cls._rollback_handle(connection)
connection.transaction_open = False
@@ -281,16 +401,14 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
@abc.abstractmethod
def execute(
self, sql: str, auto_begin: bool = False, fetch: bool = False
) -> Tuple[Union[str, AdapterResponse], agate.Table]:
) -> Tuple[AdapterResponse, agate.Table]:
"""Execute the given SQL.
:param str sql: The sql to execute.
:param bool auto_begin: If set, and dbt is not currently inside a
transaction, automatically begin one.
:param bool fetch: If set, fetch results.
:return: A tuple of the status and the results (empty if fetch=False).
:rtype: Tuple[Union[str, AdapterResponse], agate.Table]
:return: A tuple of the query status and results (empty if fetch=False).
:rtype: Tuple[AdapterResponse, agate.Table]
"""
raise dbt.exceptions.NotImplementedException(
"`execute` is not implemented for this adapter!"
)
raise dbt.exceptions.NotImplementedError("`execute` is not implemented for this adapter!")

View File

@@ -2,48 +2,63 @@ import abc
from concurrent.futures import as_completed, Future
from contextlib import contextmanager
from datetime import datetime
from enum import Enum
import time
from itertools import chain
from typing import (
Optional,
Tuple,
Callable,
Iterable,
Type,
Dict,
Any,
Callable,
Dict,
Iterable,
Iterator,
List,
Mapping,
Iterator,
Union,
Optional,
Set,
Tuple,
Type,
Union,
)
from dbt.contracts.graph.nodes import ColumnLevelConstraint, ConstraintType, ModelLevelConstraint
import agate
import pytz
from dbt.exceptions import (
raise_database_error,
raise_compiler_error,
invalid_type_error,
get_relation_returned_multiple_results,
InternalException,
NotImplementedException,
RuntimeException,
DbtInternalError,
DbtRuntimeError,
DbtValidationError,
MacroArgTypeError,
MacroResultError,
NotImplementedError,
NullRelationCacheAttemptedError,
NullRelationDropAttemptedError,
QuoteConfigTypeError,
RelationReturnedMultipleResultsError,
RenameToNoneAttemptedError,
SnapshotTargetIncompleteError,
SnapshotTargetNotSnapshotTableError,
UnexpectedNonTimestampError,
UnexpectedNullError,
)
from dbt.adapters.protocol import (
AdapterConfig,
ConnectionManagerProtocol,
)
from dbt.adapters.protocol import AdapterConfig, ConnectionManagerProtocol
from dbt.clients.agate_helper import empty_table, merge_tables, table_from_rows
from dbt.clients.jinja import MacroGenerator
from dbt.contracts.graph.compiled import CompileResultNode, CompiledSeedNode
from dbt.contracts.graph.manifest import Manifest, MacroManifest
from dbt.contracts.graph.parsed import ParsedSeedNode
from dbt.exceptions import warn_or_error
from dbt.events.functions import fire_event
from dbt.events.types import CacheMiss, ListRelations
from dbt.utils import filter_null_values, executor
from dbt.contracts.graph.nodes import ResultNode
from dbt.events.functions import fire_event, warn_or_error
from dbt.events.types import (
CacheMiss,
ListRelations,
CodeExecution,
CodeExecutionStatus,
CatalogGenerationError,
ConstraintNotSupported,
ConstraintNotEnforced,
)
from dbt.utils import filter_null_values, executor, cast_to_str, AttrDict
from dbt.adapters.base.connections import Connection, AdapterResponse
from dbt.adapters.base.meta import AdapterMeta, available
@@ -54,19 +69,23 @@ from dbt.adapters.base.relation import (
SchemaSearchMap,
)
from dbt.adapters.base import Column as BaseColumn
from dbt.adapters.cache import RelationsCache, _make_key
SeedModel = Union[ParsedSeedNode, CompiledSeedNode]
from dbt.adapters.base import Credentials
from dbt.adapters.cache import RelationsCache, _make_ref_key_dict
from dbt import deprecations
GET_CATALOG_MACRO_NAME = "get_catalog"
FRESHNESS_MACRO_NAME = "collect_freshness"
class ConstraintSupport(str, Enum):
ENFORCED = "enforced"
NOT_ENFORCED = "not_enforced"
NOT_SUPPORTED = "not_supported"
def _expect_row_value(key: str, row: agate.Row):
if key not in row.keys():
raise InternalException(
raise DbtInternalError(
'Got a row without "{}" column, columns: {}'.format(key, row.keys())
)
return row[key]
@@ -95,18 +114,10 @@ def _utc(dt: Optional[datetime], source: BaseRelation, field_name: str) -> datet
assume the datetime is already for UTC and add the timezone.
"""
if dt is None:
raise raise_database_error(
"Expected a non-null value when querying field '{}' of table "
" {} but received value 'null' instead".format(field_name, source)
)
raise UnexpectedNullError(field_name, source)
elif not hasattr(dt, "tzinfo"):
raise raise_database_error(
"Expected a timestamp value when querying field '{}' of table "
"{} but received value of type '{}' instead".format(
field_name, source, type(dt).__name__
)
)
raise UnexpectedNonTimestampError(field_name, source, dt)
elif dt.tzinfo:
return dt.astimezone(pytz.UTC)
@@ -121,6 +132,35 @@ def _relation_name(rel: Optional[BaseRelation]) -> str:
return str(rel)
def log_code_execution(code_execution_function):
# decorator to log code and execution time
if code_execution_function.__name__ != "submit_python_job":
raise ValueError("this should be only used to log submit_python_job now")
def execution_with_log(*args):
self = args[0]
connection_name = self.connections.get_thread_connection().name
fire_event(CodeExecution(conn_name=connection_name, code_content=args[2]))
start_time = time.time()
response = code_execution_function(*args)
fire_event(
CodeExecutionStatus(
status=response._message, elapsed=round((time.time() - start_time), 2)
)
)
return response
return execution_with_log
class PythonJobHelper:
def __init__(self, parsed_model: Dict, credential: Credentials) -> None:
raise NotImplementedError("PythonJobHelper is not implemented yet")
def submit(self, compiled_code: str) -> Any:
raise NotImplementedError("PythonJobHelper submit function is not implemented yet")
class BaseAdapter(metaclass=AdapterMeta):
"""The BaseAdapter provides an abstract base class for adapters.
@@ -130,9 +170,15 @@ class BaseAdapter(metaclass=AdapterMeta):
methods are marked with a (passable) in their docstrings. Check docstrings
for type information, etc.
To implement a macro, implement "${adapter_type}__${macro_name}". in the
To implement a macro, implement "${adapter_type}__${macro_name}" in the
adapter's internal project.
To invoke a method in an adapter macro, call it on the 'adapter' Jinja
object using dot syntax.
To invoke a method in model code, add the @available decorator atop a method
declaration. Methods are invoked as macros.
Methods:
- exception_handler
- date_function
@@ -141,6 +187,7 @@ class BaseAdapter(metaclass=AdapterMeta):
- truncate_relation
- rename_relation
- get_columns_in_relation
- get_column_schema_from_query
- expand_column_types
- list_relations_without_caching
- is_cancelable
@@ -153,6 +200,7 @@ class BaseAdapter(metaclass=AdapterMeta):
- convert_datetime_type
- convert_date_type
- convert_time_type
- standardize_grants_dict
Macros:
- get_catalog
@@ -166,6 +214,14 @@ class BaseAdapter(metaclass=AdapterMeta):
# for use in materializations
AdapterSpecificConfigs: Type[AdapterConfig] = AdapterConfig
CONSTRAINT_SUPPORT = {
ConstraintType.check: ConstraintSupport.NOT_SUPPORTED,
ConstraintType.not_null: ConstraintSupport.ENFORCED,
ConstraintType.unique: ConstraintSupport.NOT_ENFORCED,
ConstraintType.primary_key: ConstraintSupport.NOT_ENFORCED,
ConstraintType.foreign_key: ConstraintSupport.ENFORCED,
}
def __init__(self, config):
self.config = config
self.cache = RelationsCache()
@@ -200,9 +256,7 @@ class BaseAdapter(metaclass=AdapterMeta):
return conn.name
@contextmanager
def connection_named(
self, name: str, node: Optional[CompileResultNode] = None
) -> Iterator[None]:
def connection_named(self, name: str, node: Optional[ResultNode] = None) -> Iterator[None]:
try:
if self.connections.query_header is not None:
self.connections.query_header.set(name, node)
@@ -214,14 +268,14 @@ class BaseAdapter(metaclass=AdapterMeta):
self.connections.query_header.reset()
@contextmanager
def connection_for(self, node: CompileResultNode) -> Iterator[None]:
def connection_for(self, node: ResultNode) -> Iterator[None]:
with self.connection_named(node.unique_id, node):
yield
@available.parse(lambda *a, **k: ("", empty_table()))
def execute(
self, sql: str, auto_begin: bool = False, fetch: bool = False
) -> Tuple[Union[str, AdapterResponse], agate.Table]:
) -> Tuple[AdapterResponse, agate.Table]:
"""Execute the given SQL. This is a thin wrapper around
ConnectionManager.execute.
@@ -229,11 +283,24 @@ class BaseAdapter(metaclass=AdapterMeta):
:param bool auto_begin: If set, and dbt is not currently inside a
transaction, automatically begin one.
:param bool fetch: If set, fetch results.
:return: A tuple of the status and the results (empty if fetch=False).
:rtype: Tuple[Union[str, AdapterResponse], agate.Table]
:return: A tuple of the query status and results (empty if fetch=False).
:rtype: Tuple[AdapterResponse, agate.Table]
"""
return self.connections.execute(sql=sql, auto_begin=auto_begin, fetch=fetch)
@available.parse(lambda *a, **k: [])
def get_column_schema_from_query(self, sql: str) -> List[BaseColumn]:
"""Get a list of the Columns with names and data types from the given sql."""
_, cursor = self.connections.add_select_query(sql)
columns = [
self.Column.create(
column_name, self.connections.data_type_code_to_name(column_type_code)
)
# https://peps.python.org/pep-0249/#description
for column_name, column_type_code, *_ in cursor.description
]
return columns
@available.parse(lambda *a, **k: ("", empty_table()))
def get_partitions_metadata(self, table: str) -> Tuple[agate.Table]:
"""Obtain partitions metadata for a BigQuery partitioned table.
@@ -270,12 +337,17 @@ class BaseAdapter(metaclass=AdapterMeta):
"""
return self._macro_manifest_lazy
def load_macro_manifest(self) -> MacroManifest:
def load_macro_manifest(self, base_macros_only=False) -> MacroManifest:
# base_macros_only is for the test framework
if self._macro_manifest_lazy is None:
# avoid a circular import
from dbt.parser.manifest import ManifestLoader
manifest = ManifestLoader.load_macros(self.config, self.connections.set_query_header)
manifest = ManifestLoader.load_macros(
self.config,
self.connections.set_query_header,
base_macros_only=base_macros_only,
)
# TODO CT-211
self._macro_manifest_lazy = manifest # type: ignore[assignment]
# TODO CT-211
@@ -293,7 +365,11 @@ class BaseAdapter(metaclass=AdapterMeta):
if (database, schema) not in self.cache:
fire_event(
CacheMiss(conn_name=self.nice_connection_name(), database=database, schema=schema)
CacheMiss(
conn_name=self.nice_connection_name(),
database=cast_to_str(database),
schema=schema,
)
)
return False
else:
@@ -320,7 +396,7 @@ class BaseAdapter(metaclass=AdapterMeta):
lowercase strings.
"""
info_schema_name_map = SchemaSearchMap()
nodes: Iterator[CompileResultNode] = chain(
nodes: Iterator[ResultNode] = chain(
[
node
for node in manifest.nodes.values()
@@ -337,11 +413,14 @@ class BaseAdapter(metaclass=AdapterMeta):
# databases
return info_schema_name_map
def _relations_cache_for_schemas(self, manifest: Manifest) -> None:
def _relations_cache_for_schemas(
self, manifest: Manifest, cache_schemas: Set[BaseRelation] = None
) -> None:
"""Populate the relations cache for the given schemas. Returns an
iterable of the schemas populated, as strings.
"""
cache_schemas = self._get_cache_schemas(manifest)
if not cache_schemas:
cache_schemas = self._get_cache_schemas(manifest)
with executor(self.config) as tpe:
futures: List[Future[List[BaseRelation]]] = []
for cache_schema in cache_schemas:
@@ -367,21 +446,26 @@ class BaseAdapter(metaclass=AdapterMeta):
cache_update.add((relation.database, relation.schema))
self.cache.update_schemas(cache_update)
def set_relations_cache(self, manifest: Manifest, clear: bool = False) -> None:
def set_relations_cache(
self,
manifest: Manifest,
clear: bool = False,
required_schemas: Set[BaseRelation] = None,
) -> None:
"""Run a query that gets a populated cache of the relations in the
database and set the cache on this adapter.
"""
with self.cache.lock:
if clear:
self.cache.clear()
self._relations_cache_for_schemas(manifest)
self._relations_cache_for_schemas(manifest, required_schemas)
@available
def cache_added(self, relation: Optional[BaseRelation]) -> str:
"""Cache a new relation in dbt. It will show up in `list relations`."""
if relation is None:
name = self.nice_connection_name()
raise_compiler_error("Attempted to cache a null relation for {}".format(name))
raise NullRelationCacheAttemptedError(name)
self.cache.add(relation)
# so jinja doesn't render things
return ""
@@ -393,7 +477,7 @@ class BaseAdapter(metaclass=AdapterMeta):
"""
if relation is None:
name = self.nice_connection_name()
raise_compiler_error("Attempted to drop a null relation for {}".format(name))
raise NullRelationDropAttemptedError(name)
self.cache.drop(relation)
return ""
@@ -410,9 +494,7 @@ class BaseAdapter(metaclass=AdapterMeta):
name = self.nice_connection_name()
src_name = _relation_name(from_relation)
dst_name = _relation_name(to_relation)
raise_compiler_error(
"Attempted to rename {} to {} for {}".format(src_name, dst_name, name)
)
raise RenameToNoneAttemptedError(src_name, dst_name, name)
self.cache.rename(from_relation, to_relation)
return ""
@@ -420,14 +502,16 @@ class BaseAdapter(metaclass=AdapterMeta):
###
# Abstract methods for database-specific values, attributes, and types
###
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def date_function(cls) -> str:
"""Get the date function used by this adapter's database."""
raise NotImplementedException("`date_function` is not implemented for this adapter!")
raise NotImplementedError("`date_function` is not implemented for this adapter!")
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def is_cancelable(cls) -> bool:
raise NotImplementedException("`is_cancelable` is not implemented for this adapter!")
raise NotImplementedError("`is_cancelable` is not implemented for this adapter!")
###
# Abstract methods about schemas
@@ -435,7 +519,7 @@ class BaseAdapter(metaclass=AdapterMeta):
@abc.abstractmethod
def list_schemas(self, database: str) -> List[str]:
"""Get a list of existing schemas in database"""
raise NotImplementedException("`list_schemas` is not implemented for this adapter!")
raise NotImplementedError("`list_schemas` is not implemented for this adapter!")
@available.parse(lambda *a, **k: False)
def check_schema_exists(self, database: str, schema: str) -> bool:
@@ -458,13 +542,13 @@ class BaseAdapter(metaclass=AdapterMeta):
*Implementors must call self.cache.drop() to preserve cache state!*
"""
raise NotImplementedException("`drop_relation` is not implemented for this adapter!")
raise NotImplementedError("`drop_relation` is not implemented for this adapter!")
@abc.abstractmethod
@available.parse_none
def truncate_relation(self, relation: BaseRelation) -> None:
"""Truncate the given relation."""
raise NotImplementedException("`truncate_relation` is not implemented for this adapter!")
raise NotImplementedError("`truncate_relation` is not implemented for this adapter!")
@abc.abstractmethod
@available.parse_none
@@ -473,15 +557,13 @@ class BaseAdapter(metaclass=AdapterMeta):
Implementors must call self.cache.rename() to preserve cache state.
"""
raise NotImplementedException("`rename_relation` is not implemented for this adapter!")
raise NotImplementedError("`rename_relation` is not implemented for this adapter!")
@abc.abstractmethod
@available.parse_list
def get_columns_in_relation(self, relation: BaseRelation) -> List[BaseColumn]:
"""Get a list of the columns in the given Relation."""
raise NotImplementedException(
"`get_columns_in_relation` is not implemented for this adapter!"
)
raise NotImplementedError("`get_columns_in_relation` is not implemented for this adapter!")
@available.deprecated("get_columns_in_relation", lambda *a, **k: [])
def get_columns_in_table(self, schema: str, identifier: str) -> List[BaseColumn]:
@@ -503,7 +585,7 @@ class BaseAdapter(metaclass=AdapterMeta):
:param self.Relation current: A relation that currently exists in the
database with columns of unspecified types.
"""
raise NotImplementedException(
raise NotImplementedError(
"`expand_target_column_types` is not implemented for this adapter!"
)
@@ -518,10 +600,37 @@ class BaseAdapter(metaclass=AdapterMeta):
:return: The relations in schema
:rtype: List[self.Relation]
"""
raise NotImplementedException(
"`list_relations_without_caching` is not implemented for this " "adapter!"
raise NotImplementedError(
"`list_relations_without_caching` is not implemented for this adapter!"
)
###
# Methods about grants
###
@available
def standardize_grants_dict(self, grants_table: agate.Table) -> dict:
"""Translate the result of `show grants` (or equivalent) to match the
grants which a user would configure in their project.
Ideally, the SQL to show grants should also be filtering:
filter OUT any grants TO the current user/role (e.g. OWNERSHIP).
If that's not possible in SQL, it can be done in this method instead.
:param grants_table: An agate table containing the query result of
the SQL returned by get_show_grant_sql
:return: A standardized dictionary matching the `grants` config
:rtype: dict
"""
grants_dict: Dict[str, List[str]] = {}
for row in grants_table:
grantee = row["grantee"]
privilege = row["privilege_type"]
if privilege in grants_dict.keys():
grants_dict[privilege].append(grantee)
else:
grants_dict.update({privilege: [grantee]})
return grants_dict
###
# Provided methods about relations
###
@@ -533,7 +642,7 @@ class BaseAdapter(metaclass=AdapterMeta):
to_relation.
"""
if not isinstance(from_relation, self.Relation):
invalid_type_error(
raise MacroArgTypeError(
method_name="get_missing_columns",
arg_name="from_relation",
got_value=from_relation,
@@ -541,7 +650,7 @@ class BaseAdapter(metaclass=AdapterMeta):
)
if not isinstance(to_relation, self.Relation):
invalid_type_error(
raise MacroArgTypeError(
method_name="get_missing_columns",
arg_name="to_relation",
got_value=to_relation,
@@ -562,11 +671,11 @@ class BaseAdapter(metaclass=AdapterMeta):
expected columns.
:param Relation relation: The relation to check
:raises CompilationException: If the columns are
:raises InvalidMacroArgType: If the columns are
incorrect.
"""
if not isinstance(relation, self.Relation):
invalid_type_error(
raise MacroArgTypeError(
method_name="valid_snapshot_target",
arg_name="relation",
got_value=relation,
@@ -587,24 +696,16 @@ class BaseAdapter(metaclass=AdapterMeta):
if missing:
if extra:
msg = (
'Snapshot target has ("{}") but not ("{}") - is it an '
"unmigrated previous version archive?".format(
'", "'.join(extra), '", "'.join(missing)
)
)
raise SnapshotTargetIncompleteError(extra, missing)
else:
msg = 'Snapshot target is not a snapshot table (missing "{}")'.format(
'", "'.join(missing)
)
raise_compiler_error(msg)
raise SnapshotTargetNotSnapshotTableError(missing)
@available.parse_none
def expand_target_column_types(
self, from_relation: BaseRelation, to_relation: BaseRelation
) -> None:
if not isinstance(from_relation, self.Relation):
invalid_type_error(
raise MacroArgTypeError(
method_name="expand_target_column_types",
arg_name="from_relation",
got_value=from_relation,
@@ -612,7 +713,7 @@ class BaseAdapter(metaclass=AdapterMeta):
)
if not isinstance(to_relation, self.Relation):
invalid_type_error(
raise MacroArgTypeError(
method_name="expand_target_column_types",
arg_name="to_relation",
got_value=to_relation,
@@ -626,15 +727,32 @@ class BaseAdapter(metaclass=AdapterMeta):
return self.cache.get_relations(database, schema)
schema_relation = self.Relation.create(
database=database, schema=schema, identifier="", quote_policy=self.config.quoting
database=database,
schema=schema,
identifier="",
quote_policy=self.config.quoting,
).without_identifier()
# we can't build the relations cache because we don't have a
# manifest so we can't run any operations.
relations = self.list_relations_without_caching(schema_relation)
# if the cache is already populated, add this schema in
# otherwise, skip updating the cache and just ignore
if self.cache:
for relation in relations:
self.cache.add(relation)
if not relations:
# it's possible that there were no relations in some schemas. We want
# to insert the schemas we query into the cache's `.schemas` attribute
# so we can check it later
self.cache.update_schemas([(database, schema)])
fire_event(
ListRelations(
database=database, schema=schema, relations=[_make_key(x) for x in relations]
database=cast_to_str(database),
schema=schema,
relations=[_make_ref_key_dict(x) for x in relations],
)
)
@@ -689,7 +807,7 @@ class BaseAdapter(metaclass=AdapterMeta):
"schema": schema,
"database": database,
}
get_relation_returned_multiple_results(kwargs, matches)
raise RelationReturnedMultipleResultsError(kwargs, matches)
elif matches:
return matches[0]
@@ -711,19 +829,20 @@ class BaseAdapter(metaclass=AdapterMeta):
@available.parse_none
def create_schema(self, relation: BaseRelation):
"""Create the given schema if it does not exist."""
raise NotImplementedException("`create_schema` is not implemented for this adapter!")
raise NotImplementedError("`create_schema` is not implemented for this adapter!")
@abc.abstractmethod
@available.parse_none
def drop_schema(self, relation: BaseRelation):
"""Drop the given schema (and everything in it) if it exists."""
raise NotImplementedException("`drop_schema` is not implemented for this adapter!")
raise NotImplementedError("`drop_schema` is not implemented for this adapter!")
@available
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def quote(cls, identifier: str) -> str:
"""Quote the given identifier, as appropriate for the database."""
raise NotImplementedException("`quote` is not implemented for this adapter!")
raise NotImplementedError("`quote` is not implemented for this adapter!")
@available
def quote_as_configured(self, identifier: str, quote_key: str) -> str:
@@ -752,10 +871,7 @@ class BaseAdapter(metaclass=AdapterMeta):
elif quote_config is None:
pass
else:
raise_compiler_error(
f'The seed configuration value of "quote_columns" has an '
f"invalid type {type(quote_config)}"
)
raise QuoteConfigTypeError(quote_config)
if quote_columns:
return self.quote(column)
@@ -766,7 +882,8 @@ class BaseAdapter(metaclass=AdapterMeta):
# Conversions: These must be implemented by concrete implementations, for
# converting agate types into their sql equivalents.
###
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def convert_text_type(cls, agate_table: agate.Table, col_idx: int) -> str:
"""Return the type in the database that best maps to the agate.Text
type for the given agate table and column index.
@@ -775,9 +892,10 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column.
:return: The name of the type in the database
"""
raise NotImplementedException("`convert_text_type` is not implemented for this adapter!")
raise NotImplementedError("`convert_text_type` is not implemented for this adapter!")
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def convert_number_type(cls, agate_table: agate.Table, col_idx: int) -> str:
"""Return the type in the database that best maps to the agate.Number
type for the given agate table and column index.
@@ -786,9 +904,10 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column.
:return: The name of the type in the database
"""
raise NotImplementedException("`convert_number_type` is not implemented for this adapter!")
raise NotImplementedError("`convert_number_type` is not implemented for this adapter!")
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def convert_boolean_type(cls, agate_table: agate.Table, col_idx: int) -> str:
"""Return the type in the database that best maps to the agate.Boolean
type for the given agate table and column index.
@@ -797,11 +916,10 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column.
:return: The name of the type in the database
"""
raise NotImplementedException(
"`convert_boolean_type` is not implemented for this adapter!"
)
raise NotImplementedError("`convert_boolean_type` is not implemented for this adapter!")
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def convert_datetime_type(cls, agate_table: agate.Table, col_idx: int) -> str:
"""Return the type in the database that best maps to the agate.DateTime
type for the given agate table and column index.
@@ -810,11 +928,10 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column.
:return: The name of the type in the database
"""
raise NotImplementedException(
"`convert_datetime_type` is not implemented for this adapter!"
)
raise NotImplementedError("`convert_datetime_type` is not implemented for this adapter!")
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def convert_date_type(cls, agate_table: agate.Table, col_idx: int) -> str:
"""Return the type in the database that best maps to the agate.Date
type for the given agate table and column index.
@@ -823,9 +940,10 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column.
:return: The name of the type in the database
"""
raise NotImplementedException("`convert_date_type` is not implemented for this adapter!")
raise NotImplementedError("`convert_date_type` is not implemented for this adapter!")
@abc.abstractclassmethod
@classmethod
@abc.abstractmethod
def convert_time_type(cls, agate_table: agate.Table, col_idx: int) -> str:
"""Return the type in the database that best maps to the
agate.TimeDelta type for the given agate table and column index.
@@ -834,7 +952,7 @@ class BaseAdapter(metaclass=AdapterMeta):
:param col_idx: The index into the agate table for the column.
:return: The name of the type in the database
"""
raise NotImplementedException("`convert_time_type` is not implemented for this adapter!")
raise NotImplementedError("`convert_time_type` is not implemented for this adapter!")
@available
@classmethod
@@ -869,7 +987,7 @@ class BaseAdapter(metaclass=AdapterMeta):
context_override: Optional[Dict[str, Any]] = None,
kwargs: Dict[str, Any] = None,
text_only_columns: Optional[Iterable[str]] = None,
) -> agate.Table:
) -> AttrDict:
"""Look macro_name up in the manifest and execute its results.
:param macro_name: The name of the macro to execute.
@@ -901,7 +1019,7 @@ class BaseAdapter(metaclass=AdapterMeta):
else:
package_name = 'the "{}" package'.format(project)
raise RuntimeException(
raise DbtRuntimeError(
'dbt could not find a macro with the name "{}" in {}'.format(
macro_name, package_name
)
@@ -954,7 +1072,7 @@ class BaseAdapter(metaclass=AdapterMeta):
manifest=manifest,
)
results = self._catalog_filter_table(table, manifest)
results = self._catalog_filter_table(table, manifest) # type: ignore[arg-type]
return results
def get_catalog(self, manifest: Manifest) -> Tuple[agate.Table, List[Exception]]:
@@ -986,7 +1104,7 @@ class BaseAdapter(metaclass=AdapterMeta):
loaded_at_field: str,
filter: Optional[str],
manifest: Optional[Manifest] = None,
) -> Dict[str, Any]:
) -> Tuple[Optional[AdapterResponse], Dict[str, Any]]:
"""Calculate the freshness of sources in dbt, and return it"""
kwargs: Dict[str, Any] = {
"source": source,
@@ -995,15 +1113,23 @@ class BaseAdapter(metaclass=AdapterMeta):
}
# run the macro
table = self.execute_macro(FRESHNESS_MACRO_NAME, kwargs=kwargs, manifest=manifest)
# in older versions of dbt-core, the 'collect_freshness' macro returned the table of results directly
# starting in v1.5, by default, we return both the table and the adapter response (metadata about the query)
result: Union[
AttrDict, # current: contains AdapterResponse + agate.Table
agate.Table, # previous: just table
]
result = self.execute_macro(FRESHNESS_MACRO_NAME, kwargs=kwargs, manifest=manifest)
if isinstance(result, agate.Table):
deprecations.warn("collect-freshness-return-signature")
adapter_response = None
table = result
else:
adapter_response, table = result.response, result.table # type: ignore[attr-defined]
# now we have a 1-row table of the maximum `loaded_at_field` value and
# the current time according to the db.
if len(table) != 1 or len(table[0]) != 2:
raise_compiler_error(
'Got an invalid result from "{}" macro: {}'.format(
FRESHNESS_MACRO_NAME, [tuple(r) for r in table]
)
)
raise MacroResultError(FRESHNESS_MACRO_NAME, table)
if table[0][0] is None:
# no records in the table, so really the max_loaded_at was
# infinitely long ago. Just call it 0:00 January 1 year UTC
@@ -1013,11 +1139,12 @@ class BaseAdapter(metaclass=AdapterMeta):
snapshotted_at = _utc(table[0][1], source, loaded_at_field)
age = (snapshotted_at - max_loaded_at).total_seconds()
return {
freshness = {
"max_loaded_at": max_loaded_at,
"snapshotted_at": snapshotted_at,
"age": age,
}
return adapter_response, freshness
def pre_model_hook(self, config: Mapping[str, Any]) -> Any:
"""A hook for running some operation before the model materialization
@@ -1080,7 +1207,7 @@ class BaseAdapter(metaclass=AdapterMeta):
elif location == "prepend":
return f"'{value}' || {add_to}"
else:
raise RuntimeException(f'Got an unexpected location value of "{location}"')
raise DbtRuntimeError(f'Got an unexpected location value of "{location}"')
def get_rows_different_sql(
self,
@@ -1111,6 +1238,187 @@ class BaseAdapter(metaclass=AdapterMeta):
return sql
@property
def python_submission_helpers(self) -> Dict[str, Type[PythonJobHelper]]:
raise NotImplementedError("python_submission_helpers is not specified")
@property
def default_python_submission_method(self) -> str:
raise NotImplementedError("default_python_submission_method is not specified")
@log_code_execution
def submit_python_job(self, parsed_model: dict, compiled_code: str) -> AdapterResponse:
submission_method = parsed_model["config"].get(
"submission_method", self.default_python_submission_method
)
if submission_method not in self.python_submission_helpers:
raise NotImplementedError(
"Submission method {} is not supported for current adapter".format(
submission_method
)
)
job_helper = self.python_submission_helpers[submission_method](
parsed_model, self.connections.profile.credentials
)
submission_result = job_helper.submit(compiled_code)
# process submission result to generate adapter response
return self.generate_python_submission_response(submission_result)
def generate_python_submission_response(self, submission_result: Any) -> AdapterResponse:
raise NotImplementedError(
"Your adapter need to implement generate_python_submission_response"
)
def valid_incremental_strategies(self):
"""The set of standard builtin strategies which this adapter supports out-of-the-box.
Not used to validate custom strategies defined by end users.
"""
return ["append"]
def builtin_incremental_strategies(self):
return ["append", "delete+insert", "merge", "insert_overwrite"]
@available.parse_none
def get_incremental_strategy_macro(self, model_context, strategy: str):
# Construct macro_name from strategy name
if strategy is None:
strategy = "default"
# validate strategies for this adapter
valid_strategies = self.valid_incremental_strategies()
valid_strategies.append("default")
builtin_strategies = self.builtin_incremental_strategies()
if strategy in builtin_strategies and strategy not in valid_strategies:
raise DbtRuntimeError(
f"The incremental strategy '{strategy}' is not valid for this adapter"
)
strategy = strategy.replace("+", "_")
macro_name = f"get_incremental_{strategy}_sql"
# The model_context should have MacroGenerator callable objects for all macros
if macro_name not in model_context:
raise DbtRuntimeError(
'dbt could not find an incremental strategy macro with the name "{}" in {}'.format(
macro_name, self.config.project_name
)
)
# This returns a callable macro
return model_context[macro_name]
@classmethod
def _parse_column_constraint(cls, raw_constraint: Dict[str, Any]) -> ColumnLevelConstraint:
try:
ColumnLevelConstraint.validate(raw_constraint)
return ColumnLevelConstraint.from_dict(raw_constraint)
except Exception:
raise DbtValidationError(f"Could not parse constraint: {raw_constraint}")
@classmethod
def render_column_constraint(cls, constraint: ColumnLevelConstraint) -> Optional[str]:
"""Render the given constraint as DDL text. Should be overriden by adapters which need custom constraint
rendering."""
constraint_expression = constraint.expression or ""
rendered_column_constraint = None
if constraint.type == ConstraintType.check and constraint_expression:
rendered_column_constraint = f"check ({constraint_expression})"
elif constraint.type == ConstraintType.not_null:
rendered_column_constraint = f"not null {constraint_expression}"
elif constraint.type == ConstraintType.unique:
rendered_column_constraint = f"unique {constraint_expression}"
elif constraint.type == ConstraintType.primary_key:
rendered_column_constraint = f"primary key {constraint_expression}"
elif constraint.type == ConstraintType.foreign_key and constraint_expression:
rendered_column_constraint = f"references {constraint_expression}"
elif constraint.type == ConstraintType.custom and constraint_expression:
rendered_column_constraint = constraint_expression
if rendered_column_constraint:
rendered_column_constraint = rendered_column_constraint.strip()
return rendered_column_constraint
@available
@classmethod
def render_raw_columns_constraints(cls, raw_columns: Dict[str, Dict[str, Any]]) -> List:
rendered_column_constraints = []
for v in raw_columns.values():
col_name = cls.quote(v["name"]) if v.get("quote") else v["name"]
rendered_column_constraint = [f"{col_name} {v['data_type']}"]
for con in v.get("constraints", None):
constraint = cls._parse_column_constraint(con)
c = cls.process_parsed_constraint(constraint, cls.render_column_constraint)
if c is not None:
rendered_column_constraint.append(c)
rendered_column_constraints.append(" ".join(rendered_column_constraint))
return rendered_column_constraints
@classmethod
def process_parsed_constraint(
cls, parsed_constraint: Union[ColumnLevelConstraint, ModelLevelConstraint], render_func
) -> Optional[str]:
if (
parsed_constraint.warn_unsupported
and cls.CONSTRAINT_SUPPORT[parsed_constraint.type] == ConstraintSupport.NOT_SUPPORTED
):
warn_or_error(
ConstraintNotSupported(constraint=parsed_constraint.type.value, adapter=cls.type())
)
if (
parsed_constraint.warn_unenforced
and cls.CONSTRAINT_SUPPORT[parsed_constraint.type] == ConstraintSupport.NOT_ENFORCED
):
warn_or_error(
ConstraintNotEnforced(constraint=parsed_constraint.type.value, adapter=cls.type())
)
if cls.CONSTRAINT_SUPPORT[parsed_constraint.type] != ConstraintSupport.NOT_SUPPORTED:
return render_func(parsed_constraint)
return None
@classmethod
def _parse_model_constraint(cls, raw_constraint: Dict[str, Any]) -> ModelLevelConstraint:
try:
ModelLevelConstraint.validate(raw_constraint)
c = ModelLevelConstraint.from_dict(raw_constraint)
return c
except Exception:
raise DbtValidationError(f"Could not parse constraint: {raw_constraint}")
@available
@classmethod
def render_raw_model_constraints(cls, raw_constraints: List[Dict[str, Any]]) -> List[str]:
return [c for c in map(cls.render_raw_model_constraint, raw_constraints) if c is not None]
@classmethod
def render_raw_model_constraint(cls, raw_constraint: Dict[str, Any]) -> Optional[str]:
constraint = cls._parse_model_constraint(raw_constraint)
return cls.process_parsed_constraint(constraint, cls.render_model_constraint)
@classmethod
def render_model_constraint(cls, constraint: ModelLevelConstraint) -> Optional[str]:
"""Render the given constraint as DDL text. Should be overriden by adapters which need custom constraint
rendering."""
constraint_prefix = f"constraint {constraint.name} " if constraint.name else ""
column_list = ", ".join(constraint.columns)
if constraint.type == ConstraintType.check and constraint.expression:
return f"{constraint_prefix}check ({constraint.expression})"
elif constraint.type == ConstraintType.unique:
constraint_expression = f" {constraint.expression}" if constraint.expression else ""
return f"{constraint_prefix}unique{constraint_expression} ({column_list})"
elif constraint.type == ConstraintType.primary_key:
constraint_expression = f" {constraint.expression}" if constraint.expression else ""
return f"{constraint_prefix}primary key{constraint_expression} ({column_list})"
elif constraint.type == ConstraintType.foreign_key and constraint.expression:
return f"{constraint_prefix}foreign key ({column_list}) references {constraint.expression}"
elif constraint.type == ConstraintType.custom and constraint.expression:
return f"{constraint_prefix}{constraint.expression}"
else:
return None
COLUMNS_EQUAL_SQL = """
with diff_count as (
@@ -1158,7 +1466,7 @@ def catch_as_completed(
elif isinstance(exc, KeyboardInterrupt) or not isinstance(exc, Exception):
raise exc
else:
warn_or_error(f"Encountered an error while generating catalog: {str(exc)}")
warn_or_error(CatalogGenerationError(exc=str(exc)))
# exc is not None, derives from Exception, and isn't ctrl+c
exceptions.append(exc)
return merge_tables(tables), exceptions

View File

@@ -1,17 +1,17 @@
from typing import List, Optional, Type
from dbt.adapters.base import Credentials
from dbt.exceptions import CompilationException
from dbt.exceptions import CompilationError
from dbt.adapters.protocol import AdapterProtocol
def project_name_from_path(include_path: str) -> str:
# 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:
raise CompilationException(f"Invalid project at {include_path}: name not set!")
raise CompilationError(f"Invalid project at {include_path}: name not set!")
return partial.project_name

View File

@@ -5,9 +5,9 @@ from dbt.clients.jinja import QueryStringGenerator
from dbt.context.manifest import generate_query_header_context
from dbt.contracts.connection import AdapterRequiredConfig, QueryComment
from dbt.contracts.graph.compiled import CompileResultNode
from dbt.contracts.graph.nodes import ResultNode
from dbt.contracts.graph.manifest import Manifest
from dbt.exceptions import RuntimeException
from dbt.exceptions import DbtRuntimeError
class NodeWrapper:
@@ -48,7 +48,7 @@ class _QueryComment(local):
if isinstance(comment, str) and "*/" in comment:
# tell the user "no" so they don't hurt themselves by writing
# garbage
raise RuntimeException(f'query comment contains illegal value "*/": {comment}')
raise DbtRuntimeError(f'query comment contains illegal value "*/": {comment}')
self.query_comment = comment
self.append = append
@@ -90,7 +90,7 @@ class MacroQueryStringSetter:
def reset(self):
self.set("master", None)
def set(self, name: str, node: Optional[CompileResultNode]):
def set(self, name: str, node: Optional[ResultNode]):
wrapped: Optional[NodeWrapper] = None
if node is not None:
wrapped = NodeWrapper(node)

View File

@@ -1,9 +1,8 @@
from collections.abc import Hashable
from dataclasses import dataclass
from typing import Optional, TypeVar, Any, Type, Dict, Union, Iterator, Tuple, Set
from dataclasses import dataclass, field
from typing import Optional, TypeVar, Any, Type, Dict, Iterator, Tuple, Set
from dbt.contracts.graph.compiled import CompiledNode
from dbt.contracts.graph.parsed import ParsedSourceDefinition, ParsedNode
from dbt.contracts.graph.nodes import SourceDefinition, ManifestNode, ResultNode, ParsedNode
from dbt.contracts.relation import (
RelationType,
ComponentName,
@@ -12,7 +11,11 @@ from dbt.contracts.relation import (
Policy,
Path,
)
from dbt.exceptions import InternalException
from dbt.exceptions import (
ApproximateMatchError,
DbtInternalError,
MultipleDatabasesNotAllowedError,
)
from dbt.node_types import NodeType
from dbt.utils import filter_null_values, deep_merge, classproperty
@@ -27,8 +30,10 @@ class BaseRelation(FakeAPIObject, Hashable):
path: Path
type: Optional[RelationType] = None
quote_character: str = '"'
include_policy: Policy = Policy()
quote_policy: Policy = Policy()
# Python 3.11 requires that these use default_factory instead of simple default
# ValueError: mutable default <class 'dbt.contracts.relation.Policy'> for field include_policy is not allowed: use default_factory
include_policy: Policy = field(default_factory=lambda: Policy())
quote_policy: Policy = field(default_factory=lambda: Policy())
dbt_created: bool = False
def _is_exactish_match(self, field: ComponentName, value: str) -> bool:
@@ -39,9 +44,9 @@ class BaseRelation(FakeAPIObject, Hashable):
@classmethod
def _get_field_named(cls, field_name):
for field, _ in cls._get_fields():
if field.name == field_name:
return field
for f, _ in cls._get_fields():
if f.name == field_name:
return f
# this should be unreachable
raise ValueError(f"BaseRelation has no {field_name} field!")
@@ -52,11 +57,11 @@ class BaseRelation(FakeAPIObject, Hashable):
@classmethod
def get_default_quote_policy(cls) -> Policy:
return cls._get_field_named("quote_policy").default
return cls._get_field_named("quote_policy").default_factory()
@classmethod
def get_default_include_policy(cls) -> Policy:
return cls._get_field_named("include_policy").default
return cls._get_field_named("include_policy").default_factory()
def get(self, key, default=None):
"""Override `.get` to return a metadata object so we don't break
@@ -82,7 +87,7 @@ class BaseRelation(FakeAPIObject, Hashable):
if not search:
# nothing was passed in
raise dbt.exceptions.RuntimeException(
raise dbt.exceptions.DbtRuntimeError(
"Tried to match relation, but no search path was passed!"
)
@@ -99,7 +104,7 @@ class BaseRelation(FakeAPIObject, Hashable):
if approximate_match and not exact_match:
target = self.create(database=database, schema=schema, identifier=identifier)
dbt.exceptions.approximate_relation_match(target, self)
raise ApproximateMatchError(target, self)
return exact_match
@@ -184,7 +189,7 @@ class BaseRelation(FakeAPIObject, Hashable):
)
@classmethod
def create_from_source(cls: Type[Self], source: ParsedSourceDefinition, **kwargs: Any) -> Self:
def create_from_source(cls: Type[Self], source: SourceDefinition, **kwargs: Any) -> Self:
source_quoting = source.quoting.to_dict(omit_none=True)
source_quoting.pop("column", None)
quote_policy = deep_merge(
@@ -209,7 +214,7 @@ class BaseRelation(FakeAPIObject, Hashable):
def create_ephemeral_from_node(
cls: Type[Self],
config: HasQuoting,
node: Union[ParsedNode, CompiledNode],
node: ManifestNode,
) -> Self:
# Note that ephemeral models are based on the name.
identifier = cls.add_ephemeral_prefix(node.name)
@@ -222,7 +227,7 @@ class BaseRelation(FakeAPIObject, Hashable):
def create_from_node(
cls: Type[Self],
config: HasQuoting,
node: Union[ParsedNode, CompiledNode],
node: ManifestNode,
quote_policy: Optional[Dict[str, bool]] = None,
**kwargs: Any,
) -> Self:
@@ -243,20 +248,20 @@ class BaseRelation(FakeAPIObject, Hashable):
def create_from(
cls: Type[Self],
config: HasQuoting,
node: Union[CompiledNode, ParsedNode, ParsedSourceDefinition],
node: ResultNode,
**kwargs: Any,
) -> Self:
if node.resource_type == NodeType.Source:
if not isinstance(node, ParsedSourceDefinition):
raise InternalException(
"type mismatch, expected ParsedSourceDefinition but got {}".format(type(node))
if not isinstance(node, SourceDefinition):
raise DbtInternalError(
"type mismatch, expected SourceDefinition but got {}".format(type(node))
)
return cls.create_from_source(node, **kwargs)
else:
if not isinstance(node, (ParsedNode, CompiledNode)):
raise InternalException(
"type mismatch, expected ParsedNode or CompiledNode but "
"got {}".format(type(node))
# Can't use ManifestNode here because of parameterized generics
if not isinstance(node, (ParsedNode)):
raise DbtInternalError(
f"type mismatch, expected ManifestNode but got {type(node)}"
)
return cls.create_from_node(config, node, **kwargs)
@@ -353,7 +358,7 @@ class InformationSchema(BaseRelation):
def __post_init__(self):
if not isinstance(self.information_schema_view, (type(None), str)):
raise dbt.exceptions.CompilationException(
raise dbt.exceptions.CompilationError(
"Got an invalid name: {}".format(self.information_schema_view)
)
@@ -437,7 +442,7 @@ class SchemaSearchMap(Dict[InformationSchema, Set[Optional[str]]]):
if not allow_multiple_databases:
seen = {r.database.lower() for r in self if r.database}
if len(seen) > 1:
dbt.exceptions.raise_compiler_error(str(seen))
raise MultipleDatabasesNotAllowedError(seen)
for information_schema_name, schema in self.search():
path = {"database": information_schema_name.database, "schema": schema}

View File

@@ -2,26 +2,22 @@ import threading
from copy import deepcopy
from typing import Any, Dict, Iterable, List, Optional, Set, Tuple
from dbt.adapters.reference_keys import _make_key, _ReferenceKey
import dbt.exceptions
from dbt.events.functions import fire_event
from dbt.events.types import (
AddLink,
AddRelation,
DropCascade,
DropMissingRelation,
DropRelation,
DumpAfterAddGraph,
DumpAfterRenameSchema,
DumpBeforeAddGraph,
DumpBeforeRenameSchema,
RenameSchema,
TemporaryRelation,
UncachedRelation,
UpdateReference,
from dbt.adapters.reference_keys import (
_make_ref_key,
_make_ref_key_dict,
_ReferenceKey,
)
from dbt.exceptions import (
DependentLinkNotCachedError,
NewNameAlreadyInCacheError,
NoneRelationFoundError,
ReferencedLinkNotCachedError,
TruncatedModelNameCausedCollisionError,
)
from dbt.events.functions import fire_event, fire_event_if
from dbt.events.types import CacheAction, CacheDumpGraph
from dbt.flags import get_flags
from dbt.utils import lowercase
from dbt.helper_types import Lazy
def dot_separated(key: _ReferenceKey) -> str:
@@ -81,7 +77,7 @@ class _CachedRelation:
:return _ReferenceKey: A key for this relation.
"""
return _make_key(self)
return _make_ref_key(self)
def add_reference(self, referrer: "_CachedRelation"):
"""Add a reference from referrer to self, indicating that if this node
@@ -144,11 +140,7 @@ class _CachedRelation:
:raises InternalError: If the new key already exists.
"""
if new_key in self.referenced_by:
dbt.exceptions.raise_cache_inconsistent(
'in rename of "{}" -> "{}", new name is in the cache already'.format(
old_key, new_key
)
)
raise NewNameAlreadyInCacheError(old_key, new_key)
if old_key not in self.referenced_by:
return
@@ -237,7 +229,7 @@ class RelationsCache:
# self.relations or any cache entry's referenced_by during iteration
# it's a runtime error!
with self.lock:
return {dot_separated(k): v.dump_graph_entry() for k, v in self.relations.items()}
return {dot_separated(k): str(v.dump_graph_entry()) for k, v in self.relations.items()}
def _setdefault(self, relation: _CachedRelation):
"""Add a relation to the cache, or return it if it already exists.
@@ -264,21 +256,17 @@ class RelationsCache:
if referenced is None:
return
if referenced is None:
dbt.exceptions.raise_cache_inconsistent(
"in add_link, referenced link key {} not in cache!".format(referenced_key)
)
raise ReferencedLinkNotCachedError(referenced_key)
dependent = self.relations.get(dependent_key)
if dependent is None:
dbt.exceptions.raise_cache_inconsistent(
"in add_link, dependent link key {} not in cache!".format(dependent_key)
)
raise DependentLinkNotCachedError(dependent_key)
assert dependent is not None # we just raised!
referenced.add_reference(dependent)
# TODO: Is this dead code? I can't seem to find it grepping the codebase.
# This is called in plugins/postgres/dbt/adapters/postgres/impl.py
def add_link(self, referenced, dependent):
"""Add a link between two relations to the database. If either relation
does not exist, it will be added as an "external" relation.
@@ -293,13 +281,18 @@ class RelationsCache:
:param BaseRelation dependent: The dependent model.
:raises InternalError: If either entry does not exist.
"""
ref_key = _make_key(referenced)
dep_key = _make_key(dependent)
ref_key = _make_ref_key(referenced)
dep_key = _make_ref_key(dependent)
if (ref_key.database, ref_key.schema) not in self:
# if we have not cached the referenced schema at all, we must be
# 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.
fire_event(UncachedRelation(dep_key=dep_key, ref_key=ref_key))
fire_event(
CacheAction(
ref_key=ref_key._asdict(),
ref_key_2=dep_key._asdict(),
)
)
return
if ref_key not in self.relations:
# Insert a dummy "external" relation.
@@ -309,7 +302,13 @@ class RelationsCache:
# Insert a dummy "external" relation.
dependent = dependent.replace(type=referenced.External)
self.add(dependent)
fire_event(AddLink(dep_key=dep_key, ref_key=ref_key))
fire_event(
CacheAction(
action="add_link",
ref_key=dep_key._asdict(),
ref_key_2=ref_key._asdict(),
)
)
with self.lock:
self._add_link(ref_key, dep_key)
@@ -319,13 +318,20 @@ class RelationsCache:
:param BaseRelation relation: The underlying relation.
"""
flags = get_flags()
cached = _CachedRelation(relation)
fire_event(AddRelation(relation=_make_key(cached)))
fire_event(DumpBeforeAddGraph(dump=Lazy.defer(lambda: self.dump_graph())))
fire_event_if(
flags.LOG_CACHE_EVENTS,
lambda: CacheDumpGraph(before_after="before", action="adding", dump=self.dump_graph()),
)
fire_event(CacheAction(action="add_relation", ref_key=_make_ref_key_dict(cached)))
with self.lock:
self._setdefault(cached)
fire_event(DumpAfterAddGraph(dump=Lazy.defer(lambda: self.dump_graph())))
fire_event_if(
flags.LOG_CACHE_EVENTS,
lambda: CacheDumpGraph(before_after="after", action="adding", dump=self.dump_graph()),
)
def _remove_refs(self, keys):
"""Removes all references to all entries in keys. This does not
@@ -340,19 +346,6 @@ class RelationsCache:
for cached in self.relations.values():
cached.release_references(keys)
def _drop_cascade_relation(self, dropped_key):
"""Drop the given relation and cascade it appropriately to all
dependent relations.
:param _CachedRelation dropped: An existing _CachedRelation to drop.
"""
if dropped_key not in self.relations:
fire_event(DropMissingRelation(relation=dropped_key))
return
consequences = self.relations[dropped_key].collect_consequences()
fire_event(DropCascade(dropped=dropped_key, consequences=consequences))
self._remove_refs(consequences)
def drop(self, relation):
"""Drop the named relation and cascade it appropriately to all
dependent relations.
@@ -364,10 +357,22 @@ class RelationsCache:
:param str schema: The schema of the relation to drop.
:param str identifier: The identifier of the relation to drop.
"""
dropped_key = _make_key(relation)
fire_event(DropRelation(dropped=dropped_key))
dropped_key = _make_ref_key(relation)
dropped_key_msg = _make_ref_key_dict(relation)
fire_event(CacheAction(action="drop_relation", ref_key=dropped_key_msg))
with self.lock:
self._drop_cascade_relation(dropped_key)
if dropped_key not in self.relations:
fire_event(CacheAction(action="drop_missing_relation", ref_key=dropped_key_msg))
return
consequences = self.relations[dropped_key].collect_consequences()
# convert from a list of _ReferenceKeys to a list of ReferenceKeyMsgs
consequence_msgs = [key._asdict() for key in consequences]
fire_event(
CacheAction(
action="drop_cascade", ref_key=dropped_key_msg, ref_list=consequence_msgs
)
)
self._remove_refs(consequences)
def _rename_relation(self, old_key, new_relation):
"""Rename a relation named old_key to new_key, updating references.
@@ -383,14 +388,20 @@ class RelationsCache:
relation = self.relations.pop(old_key)
new_key = new_relation.key()
# relaton has to rename its innards, so it needs the _CachedRelation.
# relation has to rename its innards, so it needs the _CachedRelation.
relation.rename(new_relation)
# update all the relations that refer to it
for cached in self.relations.values():
if cached.is_referenced_by(old_key):
fire_event(
UpdateReference(old_key=old_key, new_key=new_key, cached_key=cached.key())
CacheAction(
action="update_reference",
ref_key=_make_ref_key_dict(old_key),
ref_key_2=_make_ref_key_dict(new_key),
ref_key_3=_make_ref_key_dict(cached.key()),
)
)
cached.rename_key(old_key, new_key)
self.relations[new_key] = relation
@@ -413,14 +424,12 @@ class RelationsCache:
:raises InternalError: If the new key is already present.
"""
if new_key in self.relations:
dbt.exceptions.raise_cache_inconsistent(
"in rename, new key {} already in cache: {}".format(
new_key, list(self.relations.keys())
)
)
# Tell user when collision caused by model names truncated during
# materialization.
raise TruncatedModelNameCausedCollisionError(new_key, self.relations)
if old_key not in self.relations:
fire_event(TemporaryRelation(key=old_key))
fire_event(CacheAction(action="temporary_relation", ref_key=old_key._asdict()))
return False
return True
@@ -436,11 +445,20 @@ class RelationsCache:
:param BaseRelation new: The new relation name information.
:raises InternalError: If the new key is already present.
"""
old_key = _make_key(old)
new_key = _make_key(new)
fire_event(RenameSchema(old_key=old_key, new_key=new_key))
fire_event(DumpBeforeRenameSchema(dump=Lazy.defer(lambda: self.dump_graph())))
old_key = _make_ref_key(old)
new_key = _make_ref_key(new)
fire_event(
CacheAction(
action="rename_relation",
ref_key=old_key._asdict(),
ref_key_2=new_key._asdict(),
)
)
flags = get_flags()
fire_event_if(
flags.LOG_CACHE_EVENTS,
lambda: CacheDumpGraph(before_after="before", action="rename", dump=self.dump_graph()),
)
with self.lock:
if self._check_rename_constraints(old_key, new_key):
@@ -448,7 +466,10 @@ class RelationsCache:
else:
self._setdefault(_CachedRelation(new))
fire_event(DumpAfterRenameSchema(dump=Lazy.defer(lambda: self.dump_graph())))
fire_event_if(
flags.LOG_CACHE_EVENTS,
lambda: CacheDumpGraph(before_after="after", action="rename", dump=self.dump_graph()),
)
def get_relations(self, database: Optional[str], schema: Optional[str]) -> List[Any]:
"""Case-insensitively yield all relations matching the given schema.
@@ -467,9 +488,7 @@ class RelationsCache:
]
if None in results:
dbt.exceptions.raise_cache_inconsistent(
"in get_relations, a None relation was found in the cache!"
)
raise NoneRelationFoundError()
return results
def clear(self):
@@ -496,6 +515,6 @@ class RelationsCache:
"""
for relation in to_remove:
# it may have been cascaded out already
drop_key = _make_key(relation)
drop_key = _make_ref_key(relation)
if drop_key in self.relations:
self.drop(drop_key)

View File

@@ -1,23 +1,19 @@
import threading
from pathlib import Path
import traceback
from contextlib import contextmanager
from importlib import import_module
from typing import Type, Dict, Any, List, Optional, Set
from pathlib import Path
from typing import Any, Dict, List, Optional, Set, Type
from dbt.exceptions import RuntimeException, InternalException
from dbt.include.global_project import (
PACKAGE_PATH as GLOBAL_PROJECT_PATH,
PROJECT_NAME as GLOBAL_PROJECT_NAME,
)
from dbt.events.functions import fire_event
from dbt.events.types import AdapterImportError, PluginLoadError
from dbt.contracts.connection import Credentials, AdapterRequiredConfig
from dbt.adapters.protocol import (
AdapterProtocol,
AdapterConfig,
RelationProtocol,
)
from dbt.adapters.base.plugin import AdapterPlugin
from dbt.adapters.protocol import AdapterConfig, AdapterProtocol, RelationProtocol
from dbt.contracts.connection import AdapterRequiredConfig, Credentials
from dbt.events.functions import fire_event
from dbt.events.types import AdapterImportError, PluginLoadError, AdapterRegistered
from dbt.exceptions import DbtInternalError, DbtRuntimeError
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.semver import VersionSpecifier
Adapter = AdapterProtocol
@@ -39,7 +35,7 @@ class AdapterContainer:
names = ", ".join(self.plugins.keys())
message = f"Invalid adapter type {name}! Must be one of {names}"
raise RuntimeException(message)
raise DbtRuntimeError(message)
def get_adapter_class_by_name(self, name: str) -> Type[Adapter]:
plugin = self.get_plugin_by_name(name)
@@ -64,18 +60,18 @@ class AdapterContainer:
# if we failed to import the target module in particular, inform
# the user about it via a runtime error
if exc.name == "dbt.adapters." + name:
fire_event(AdapterImportError(exc=exc))
raise RuntimeException(f"Could not find adapter type {name}!")
fire_event(AdapterImportError(exc=str(exc)))
raise DbtRuntimeError(f"Could not find adapter type {name}!")
# otherwise, the error had to have come from some underlying
# library. Log the stack trace.
fire_event(PluginLoadError())
fire_event(PluginLoadError(exc_info=traceback.format_exc()))
raise
plugin: AdapterPlugin = mod.Plugin
plugin_type = plugin.adapter.type()
if plugin_type != name:
raise RuntimeException(
raise DbtRuntimeError(
f"Expected to find adapter with type named {name}, got "
f"adapter with type {plugin_type}"
)
@@ -94,7 +90,13 @@ class AdapterContainer:
def register_adapter(self, config: AdapterRequiredConfig) -> None:
adapter_name = config.credentials.type
adapter_type = self.get_adapter_class_by_name(adapter_name)
adapter_version = import_module(f".{adapter_name}.__version__", "dbt.adapters").version
adapter_version_specifier = VersionSpecifier.from_version_string(
adapter_version
).to_version_string()
fire_event(
AdapterRegistered(adapter_name=adapter_name, adapter_version=adapter_version_specifier)
)
with self.lock:
if adapter_name in self.adapters:
# this shouldn't really happen...
@@ -137,11 +139,9 @@ class AdapterContainer:
try:
plugin = self.plugins[plugin_name]
except KeyError:
raise InternalException(f"No plugin found for {plugin_name}") from None
raise DbtInternalError(f"No plugin found for {plugin_name}") from None
plugins.append(plugin)
seen.add(plugin_name)
if plugin.dependencies is None:
continue
for dep in plugin.dependencies:
if dep not in seen:
plugin_names.append(dep)
@@ -158,7 +158,7 @@ class AdapterContainer:
try:
path = self.packages[package_name]
except KeyError:
raise InternalException(f"No internal package listing found for {package_name}")
raise DbtInternalError(f"No internal package listing found for {package_name}")
paths.append(path)
return paths
@@ -177,6 +177,10 @@ def get_adapter(config: AdapterRequiredConfig):
return FACTORY.lookup_adapter(config.credentials.type)
def get_adapter_by_type(adapter_type):
return FACTORY.lookup_adapter(adapter_type)
def reset_adapters():
"""Clear the adapters. This is useful for tests, which change configs."""
FACTORY.reset_adapters()
@@ -215,3 +219,12 @@ def get_adapter_package_names(name: Optional[str]) -> List[str]:
def get_adapter_type_names(name: Optional[str]) -> List[str]:
return FACTORY.get_adapter_type_names(name)
@contextmanager
def adapter_management():
reset_adapters()
try:
yield
finally:
cleanup_connections()

View File

@@ -7,9 +7,7 @@ from typing import (
List,
Generic,
TypeVar,
ClassVar,
Tuple,
Union,
Dict,
Any,
)
@@ -18,8 +16,7 @@ from typing_extensions import Protocol
import agate
from dbt.contracts.connection import Connection, AdapterRequiredConfig, AdapterResponse
from dbt.contracts.graph.compiled import CompiledNode, ManifestNode, NonSourceCompiledNode
from dbt.contracts.graph.parsed import ParsedNode, ParsedSourceDefinition
from dbt.contracts.graph.nodes import ResultNode, ManifestNode
from dbt.contracts.graph.model_config import BaseConfig
from dbt.contracts.graph.manifest import Manifest
from dbt.contracts.relation import Policy, HasQuoting
@@ -49,11 +46,7 @@ class RelationProtocol(Protocol):
...
@classmethod
def create_from(
cls: Type[Self],
config: HasQuoting,
node: Union[CompiledNode, ParsedNode, ParsedSourceDefinition],
) -> Self:
def create_from(cls: Type[Self], config: HasQuoting, node: ResultNode) -> Self:
...
@@ -66,7 +59,7 @@ class CompilerProtocol(Protocol):
node: ManifestNode,
manifest: Manifest,
extra_context: Optional[Dict[str, Any]] = None,
) -> NonSourceCompiledNode:
) -> ManifestNode:
...
@@ -88,10 +81,13 @@ class AdapterProtocol( # type: ignore[misc]
Compiler_T,
],
):
AdapterSpecificConfigs: ClassVar[Type[AdapterConfig_T]]
Column: ClassVar[Type[Column_T]]
Relation: ClassVar[Type[Relation_T]]
ConnectionManager: ClassVar[Type[ConnectionManager_T]]
# N.B. Technically these are ClassVars, but mypy doesn't support putting type vars in a
# ClassVar due to the restrictiveness of PEP-526
# See: https://github.com/python/mypy/issues/5144
AdapterSpecificConfigs: Type[AdapterConfig_T]
Column: Type[Column_T]
Relation: Type[Relation_T]
ConnectionManager: Type[ConnectionManager_T]
connections: ConnectionManager_T
def __init__(self, config: AdapterRequiredConfig):
@@ -155,7 +151,7 @@ class AdapterProtocol( # type: ignore[misc]
def execute(
self, sql: str, auto_begin: bool = False, fetch: bool = False
) -> Tuple[Union[str, AdapterResponse], agate.Table]:
) -> Tuple[AdapterResponse, agate.Table]:
...
def get_compiler(self) -> Compiler_T:

View File

@@ -1,7 +1,7 @@
# this module exists to resolve circular imports with the events module
from collections import namedtuple
from typing import Optional
from typing import Any, Optional
_ReferenceKey = namedtuple("_ReferenceKey", "database schema identifier")
@@ -14,7 +14,12 @@ def lowercase(value: Optional[str]) -> Optional[str]:
return value.lower()
def _make_key(relation) -> _ReferenceKey:
# For backwards compatibility. New code should use _make_ref_key
def _make_key(relation: Any) -> _ReferenceKey:
return _make_ref_key(relation)
def _make_ref_key(relation: Any) -> _ReferenceKey:
"""Make _ReferenceKeys with lowercase values for the cache so we don't have
to keep track of quoting
"""
@@ -22,3 +27,11 @@ def _make_key(relation) -> _ReferenceKey:
return _ReferenceKey(
lowercase(relation.database), lowercase(relation.schema), lowercase(relation.identifier)
)
def _make_ref_key_dict(relation: Any):
return {
"database": relation.database,
"schema": relation.schema,
"identifier": relation.identifier,
}

View File

@@ -10,6 +10,8 @@ from dbt.adapters.base import BaseConnectionManager
from dbt.contracts.connection import Connection, ConnectionState, AdapterResponse
from dbt.events.functions import fire_event
from dbt.events.types import ConnectionUsed, SQLQuery, SQLCommit, SQLQueryStatus
from dbt.events.contextvars import get_node_info
from dbt.utils import cast_to_str
class SQLConnectionManager(BaseConnectionManager):
@@ -25,9 +27,7 @@ class SQLConnectionManager(BaseConnectionManager):
@abc.abstractmethod
def cancel(self, connection: Connection):
"""Cancel the given connection."""
raise dbt.exceptions.NotImplementedException(
"`cancel` is not implemented for this adapter!"
)
raise dbt.exceptions.NotImplementedError("`cancel` is not implemented for this adapter!")
def cancel_open(self) -> List[str]:
names = []
@@ -52,10 +52,17 @@ class SQLConnectionManager(BaseConnectionManager):
bindings: Optional[Any] = None,
abridge_sql_log: bool = False,
) -> Tuple[Connection, Any]:
connection = self.get_thread_connection()
if auto_begin and connection.transaction_open is False:
self.begin()
fire_event(ConnectionUsed(conn_type=self.TYPE, conn_name=connection.name))
fire_event(
ConnectionUsed(
conn_type=self.TYPE,
conn_name=cast_to_str(connection.name),
node_info=get_node_info(),
)
)
with self.exception_handler(sql):
if abridge_sql_log:
@@ -63,7 +70,11 @@ class SQLConnectionManager(BaseConnectionManager):
else:
log_sql = sql
fire_event(SQLQuery(conn_name=connection.name, sql=log_sql))
fire_event(
SQLQuery(
conn_name=cast_to_str(connection.name), sql=log_sql, node_info=get_node_info()
)
)
pre = time.time()
cursor = connection.handle.cursor()
@@ -71,16 +82,19 @@ class SQLConnectionManager(BaseConnectionManager):
fire_event(
SQLQueryStatus(
status=str(self.get_response(cursor)), elapsed=round((time.time() - pre), 2)
status=str(self.get_response(cursor)),
elapsed=round((time.time() - pre)),
node_info=get_node_info(),
)
)
return connection, cursor
@abc.abstractclassmethod
def get_response(cls, cursor: Any) -> Union[AdapterResponse, str]:
@classmethod
@abc.abstractmethod
def get_response(cls, cursor: Any) -> AdapterResponse:
"""Get the status of the cursor."""
raise dbt.exceptions.NotImplementedException(
raise dbt.exceptions.NotImplementedError(
"`get_response` is not implemented for this adapter!"
)
@@ -115,9 +129,17 @@ class SQLConnectionManager(BaseConnectionManager):
return dbt.clients.agate_helper.table_from_data_flat(data, column_names)
@classmethod
def data_type_code_to_name(cls, type_code: Union[int, str]) -> str:
"""Get the string representation of the data type from the type_code."""
# https://peps.python.org/pep-0249/#type-objects
raise dbt.exceptions.NotImplementedError(
"`data_type_code_to_name` is not implemented for this adapter!"
)
def execute(
self, sql: str, auto_begin: bool = False, fetch: bool = False
) -> Tuple[Union[AdapterResponse, str], agate.Table]:
) -> Tuple[AdapterResponse, agate.Table]:
sql = self._add_query_comment(sql)
_, cursor = self.add_query(sql, auto_begin)
response = self.get_response(cursor)
@@ -133,10 +155,14 @@ class SQLConnectionManager(BaseConnectionManager):
def add_commit_query(self):
return self.add_query("COMMIT", auto_begin=False)
def add_select_query(self, sql: str) -> Tuple[Connection, Any]:
sql = self._add_query_comment(sql)
return self.add_query(sql, auto_begin=False)
def begin(self):
connection = self.get_thread_connection()
if connection.transaction_open is True:
raise dbt.exceptions.InternalException(
raise dbt.exceptions.DbtInternalError(
'Tried to begin a new transaction on connection "{}", but '
"it already had one open!".format(connection.name)
)
@@ -149,12 +175,12 @@ class SQLConnectionManager(BaseConnectionManager):
def commit(self):
connection = self.get_thread_connection()
if connection.transaction_open is False:
raise dbt.exceptions.InternalException(
raise dbt.exceptions.DbtInternalError(
'Tried to commit transaction on connection "{}", but '
"it does not have one open!".format(connection.name)
)
fire_event(SQLCommit(conn_name=connection.name))
fire_event(SQLCommit(conn_name=connection.name, node_info=get_node_info()))
self.add_commit_query()
connection.transaction_open = False

View File

@@ -1,11 +1,10 @@
import agate
from typing import Any, Optional, Tuple, Type, List
import dbt.clients.agate_helper
from dbt.contracts.connection import Connection
import dbt.exceptions
from dbt.exceptions import RelationTypeNullError
from dbt.adapters.base import BaseAdapter, available
from dbt.adapters.cache import _make_key
from dbt.adapters.cache import _make_ref_key_dict
from dbt.adapters.sql import SQLConnectionManager
from dbt.events.functions import fire_event
from dbt.events.types import ColTypeChange, SchemaCreation, SchemaDrop
@@ -27,7 +26,7 @@ ALTER_COLUMN_TYPE_MACRO_NAME = "alter_column_type"
class SQLAdapter(BaseAdapter):
"""The default adapter with the common agate conversions and some SQL
methods implemented. This adapter has a different much shorter list of
methods was implemented. This adapter has a different much shorter list of
methods to implement, but some more macros that must be implemented.
To implement a macro, implement "${adapter_type}__${macro_name}". in the
@@ -110,7 +109,7 @@ class SQLAdapter(BaseAdapter):
ColTypeChange(
orig_type=target_column.data_type,
new_type=new_type,
table=_make_key(current),
table=_make_ref_key_dict(current),
)
)
@@ -132,9 +131,7 @@ class SQLAdapter(BaseAdapter):
def drop_relation(self, relation):
if relation.type is None:
dbt.exceptions.raise_compiler_error(
"Tried to drop relation {}, but its type is null.".format(relation)
)
raise RelationTypeNullError(relation)
self.cache_dropped(relation)
self.execute_macro(DROP_RELATION_MACRO_NAME, kwargs={"relation": relation})
@@ -155,7 +152,7 @@ class SQLAdapter(BaseAdapter):
def create_schema(self, relation: BaseRelation) -> None:
relation = relation.without_identifier()
fire_event(SchemaCreation(relation=_make_key(relation)))
fire_event(SchemaCreation(relation=_make_ref_key_dict(relation)))
kwargs = {
"relation": relation,
}
@@ -166,11 +163,12 @@ class SQLAdapter(BaseAdapter):
def drop_schema(self, relation: BaseRelation) -> None:
relation = relation.without_identifier()
fire_event(SchemaDrop(relation=_make_key(relation)))
fire_event(SchemaDrop(relation=_make_ref_key_dict(relation)))
kwargs = {
"relation": relation,
}
self.execute_macro(DROP_SCHEMA_MACRO_NAME, kwargs=kwargs)
self.commit_if_has_connection()
# we can update the cache here
self.cache.drop_schema(relation.database, relation.schema)
@@ -199,6 +197,7 @@ class SQLAdapter(BaseAdapter):
)
return relations
@classmethod
def quote(self, identifier):
return '"{}"'.format(identifier)
@@ -218,3 +217,25 @@ class SQLAdapter(BaseAdapter):
kwargs = {"information_schema": information_schema, "schema": schema}
results = self.execute_macro(CHECK_SCHEMA_EXISTS_MACRO_NAME, kwargs=kwargs)
return results[0][0] > 0
# This is for use in the test suite
def run_sql_for_tests(self, sql, fetch, conn):
cursor = conn.handle.cursor()
try:
cursor.execute(sql)
if hasattr(conn.handle, "commit"):
conn.handle.commit()
if fetch == "one":
return cursor.fetchone()
elif fetch == "all":
return cursor.fetchall()
else:
return
except BaseException as e:
if conn.handle and not getattr(conn.handle, "closed", True):
conn.handle.rollback()
print(sql)
print(e)
raise
finally:
conn.transaction_open = False

49
core/dbt/cli/README.md Normal file
View File

@@ -0,0 +1,49 @@
# Exception Handling
## `requires.py`
### `postflight`
In the postflight decorator, the click command is invoked (i.e. `func(*args, **kwargs)`) and wrapped in a `try/except` block to handle any exceptions thrown.
Any exceptions thrown from `postflight` are wrapped by custom exceptions from the `dbt.cli.exceptions` module (i.e. `ResultExit`, `ExceptionExit`) to instruct click to complete execution with a particular exit code.
Some `dbt-core` handled exceptions have an attribute named `results` which contains results from running nodes (e.g. `FailFastError`). These are wrapped in the `ResultExit` exception to represent runs that have failed in a way that `dbt-core` expects.
If the invocation of the command does not throw any exceptions but does not succeed, `postflight` will still raise the `ResultExit` exception to make use of the exit code.
These exceptions produce an exit code of `1`.
Exceptions wrapped with `ExceptionExit` may be thrown by `dbt-core` intentionally (i.e. an exception that inherits from `dbt.exceptions.Exception`) or unintentionally (i.e. exceptions thrown by the python runtime). In either case these are considered errors that `dbt-core` did not expect and are treated as genuine exceptions.
These exceptions produce an exit code of `2`.
If no exceptions are thrown from invoking the command and the command succeeds, `postflight` will not raise any exceptions.
When no exceptions are raised an exit code of `0` is produced.
## `main.py`
### `dbtRunner`
`dbtRunner` provides a programmatic interface for our click CLI and wraps the invocation of the click commands to handle any exceptions thrown.
`dbtRunner.invoke` should ideally only ever return an instantiated `dbtRunnerResult` which contains the following fields:
- `success`: A boolean representing whether the command invocation was successful
- `result`: The optional result of the command invoked. This attribute can have many types, please see the definition of `dbtRunnerResult` for more information
- `exception`: If an exception was thrown during command invocation it will be saved here, otherwise it will be `None`. Please note that the exceptions held in this attribute are not the exceptions thrown by `preflight` but instead the exceptions that `ResultExit` and `ExceptionExit` wrap
Programmatic exception handling might look like the following:
```python
res = dbtRunner().invoke(["run"])
if not res.success:
...
if type(res.exception) == SomeExceptionType:
...
```
## `dbt/tests/util.py`
### `run_dbt`
In many of our functional and integration tests, we want to be sure that an invocation of `dbt` raises a certain exception.
A common pattern for these assertions:
```python
class TestSomething:
def test_something(self, project):
with pytest.raises(SomeException):
run_dbt(["run"])
```
To allow these tests to assert that exceptions have been thrown, the `run_dbt` function will raise any exceptions it recieves from the invocation of a `dbt` command.

1
core/dbt/cli/__init__.py Normal file
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

View File

@@ -0,0 +1,43 @@
from typing import Optional, IO
from click.exceptions import ClickException
from dbt.utils import ExitCodes
class DbtUsageException(Exception):
pass
class DbtInternalException(Exception):
pass
class CliException(ClickException):
"""The base exception class for our implementation of the click CLI.
The exit_code attribute is used by click to determine which exit code to produce
after an invocation."""
def __init__(self, exit_code: ExitCodes) -> None:
self.exit_code = exit_code.value
# the typing of _file is to satisfy the signature of ClickException.show
# overriding this method prevents click from printing any exceptions to stdout
def show(self, _file: Optional[IO] = None) -> None:
pass
class ResultExit(CliException):
"""This class wraps any exception that contains results while invoking dbt, or the
results of an invocation that did not succeed but did not throw any exceptions."""
def __init__(self, result) -> None:
super().__init__(ExitCodes.ModelError)
self.result = result
class ExceptionExit(CliException):
"""This class wraps any exception that does not contain results thrown while invoking dbt."""
def __init__(self, exception: Exception) -> None:
super().__init__(ExitCodes.UnhandledError)
self.exception = exception

279
core/dbt/cli/flags.py Normal file
View File

@@ -0,0 +1,279 @@
import os
import sys
from dataclasses import dataclass
from importlib import import_module
from multiprocessing import get_context
from pprint import pformat as pf
from typing import Callable, Dict, List, Set, Union
from click import Context, get_current_context
from click.core import Command, Group, ParameterSource
from dbt.cli.exceptions import DbtUsageException
from dbt.cli.resolvers import default_log_path, default_project_dir
from dbt.config.profile import read_user_config
from dbt.contracts.project import UserConfig
from dbt.deprecations import renamed_env_var
from dbt.helper_types import WarnErrorOptions
if os.name != "nt":
# https://bugs.python.org/issue41567
import multiprocessing.popen_spawn_posix # type: ignore # noqa: F401
FLAGS_DEFAULTS = {
"INDIRECT_SELECTION": "eager",
"TARGET_PATH": None,
# Cli args without user_config or env var option.
"FULL_REFRESH": False,
"STRICT_MODE": False,
"STORE_FAILURES": False,
"INTROSPECT": True,
}
DEPRECATED_PARAMS = {
"deprecated_defer": "defer",
"deprecated_favor_state": "favor_state",
"deprecated_print": "print",
"deprecated_state": "state",
}
def convert_config(config_name, config_value):
"""Convert the values from config and original set_from_args to the correct type."""
ret = config_value
if config_name.lower() == "warn_error_options" and type(config_value) == dict:
ret = WarnErrorOptions(
include=config_value.get("include", []), exclude=config_value.get("exclude", [])
)
return ret
def args_to_context(args: List[str]) -> Context:
"""Convert a list of args to a click context with proper hierarchy for dbt commands"""
from dbt.cli.main import cli
cli_ctx = cli.make_context(cli.name, args)
# Split args if they're a comma separated string.
if len(args) == 1 and "," in args[0]:
args = args[0].split(",")
sub_command_name, sub_command, args = cli.resolve_command(cli_ctx, args)
# Handle source and docs group.
if type(sub_command) == Group:
sub_command_name, sub_command, args = sub_command.resolve_command(cli_ctx, args)
assert type(sub_command) == Command
sub_command_ctx = sub_command.make_context(sub_command_name, args)
sub_command_ctx.parent = cli_ctx
return sub_command_ctx
@dataclass(frozen=True)
class Flags:
"""Primary configuration artifact for running dbt"""
def __init__(self, ctx: Context = None, user_config: UserConfig = None) -> None:
# Set the default flags.
for key, value in FLAGS_DEFAULTS.items():
object.__setattr__(self, key, value)
if ctx is None:
ctx = get_current_context()
def _get_params_by_source(ctx: Context, source_type: ParameterSource):
"""Generates all params of a given source type."""
yield from [
name for name, source in ctx._parameter_source.items() if source is source_type
]
if ctx.parent:
yield from _get_params_by_source(ctx.parent, source_type)
# Ensure that any params sourced from the commandline are not present more than once.
# Click handles this exclusivity, but only at a per-subcommand level.
seen_params = []
for param in _get_params_by_source(ctx, ParameterSource.COMMANDLINE):
if param in seen_params:
raise DbtUsageException(
f"{param.lower()} was provided both before and after the subcommand, it can only be set either before or after.",
)
seen_params.append(param)
def _assign_params(
ctx: Context,
params_assigned_from_default: set,
deprecated_env_vars: Dict[str, Callable],
):
"""Recursively adds all click params to flag object"""
for param_name, param_value in ctx.params.items():
# N.B. You have to use the base MRO method (object.__setattr__) to set attributes
# when using frozen dataclasses.
# https://docs.python.org/3/library/dataclasses.html#frozen-instances
# Handle deprecated env vars while still respecting old values
# e.g. DBT_NO_PRINT -> DBT_PRINT if DBT_NO_PRINT is set, it is
# respected over DBT_PRINT or --print.
new_name: Union[str, None] = None
if param_name in DEPRECATED_PARAMS:
# Deprecated env vars can only be set via env var.
# We use the deprecated option in click to serialize the value
# from the env var string.
param_source = ctx.get_parameter_source(param_name)
if param_source == ParameterSource.DEFAULT:
continue
elif param_source != ParameterSource.ENVIRONMENT:
raise DbtUsageException(
"Deprecated parameters can only be set via environment variables",
)
# Rename for clarity.
dep_name = param_name
new_name = DEPRECATED_PARAMS.get(dep_name)
try:
assert isinstance(new_name, str)
except AssertionError:
raise Exception(
f"No deprecated param name match in DEPRECATED_PARAMS from {dep_name} to {new_name}"
)
# Find param objects for their envvar name.
try:
dep_param = [x for x in ctx.command.params if x.name == dep_name][0]
new_param = [x for x in ctx.command.params if x.name == new_name][0]
except IndexError:
raise Exception(
f"No deprecated param name match in context from {dep_name} to {new_name}"
)
# Remove param from defaulted set since the deprecated
# value is not set from default, but from an env var.
if new_name in params_assigned_from_default:
params_assigned_from_default.remove(new_name)
# Add the deprecation warning function to the set.
assert isinstance(dep_param.envvar, str)
assert isinstance(new_param.envvar, str)
deprecated_env_vars[new_name] = renamed_env_var(
old_name=dep_param.envvar,
new_name=new_param.envvar,
)
# Set the flag value.
is_duplicate = hasattr(self, param_name.upper())
is_default = ctx.get_parameter_source(param_name) == ParameterSource.DEFAULT
flag_name = (new_name or param_name).upper()
if (is_duplicate and not is_default) or not is_duplicate:
object.__setattr__(self, flag_name, param_value)
# Track default assigned params.
if is_default:
params_assigned_from_default.add(param_name)
if ctx.parent:
_assign_params(ctx.parent, params_assigned_from_default, deprecated_env_vars)
params_assigned_from_default = set() # type: Set[str]
deprecated_env_vars: Dict[str, Callable] = {}
_assign_params(ctx, params_assigned_from_default, deprecated_env_vars)
# Set deprecated_env_var_warnings to be fired later after events have been init.
object.__setattr__(
self, "deprecated_env_var_warnings", [x for x in deprecated_env_vars.values()]
)
# 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, deprecated_env_vars
)
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:
param_assigned_from_default_copy = params_assigned_from_default.copy()
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(),
convert_config(param_assigned_from_default, user_config_param_value),
)
param_assigned_from_default_copy.remove(param_assigned_from_default)
params_assigned_from_default = param_assigned_from_default_copy
# Set hard coded flags.
object.__setattr__(self, "WHICH", invoked_subcommand_name or ctx.info_name)
object.__setattr__(self, "MP_CONTEXT", get_context("spawn"))
# Apply the lead/follow relationship between some parameters.
self._override_if_set("USE_COLORS", "USE_COLORS_FILE", params_assigned_from_default)
self._override_if_set("LOG_LEVEL", "LOG_LEVEL_FILE", params_assigned_from_default)
self._override_if_set("LOG_FORMAT", "LOG_FORMAT_FILE", params_assigned_from_default)
# Set default LOG_PATH from PROJECT_DIR, if available.
# Starting in v1.5, if `log-path` is set in `dbt_project.yml`, it will raise a deprecation warning,
# with the possibility of removing it in a future release.
if getattr(self, "LOG_PATH", None) is None:
project_dir = getattr(self, "PROJECT_DIR", default_project_dir())
version_check = getattr(self, "VERSION_CHECK", True)
object.__setattr__(self, "LOG_PATH", default_log_path(project_dir, version_check))
# Support console DO NOT TRACK initiative.
if os.getenv("DO_NOT_TRACK", "").lower() in ("1", "t", "true", "y", "yes"):
object.__setattr__(self, "SEND_ANONYMOUS_USAGE_STATS", False)
# Check mutual exclusivity once all flags are set.
self._assert_mutually_exclusive(
params_assigned_from_default, ["WARN_ERROR", "WARN_ERROR_OPTIONS"]
)
# 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:
return str(pf(self.__dict__))
def _override_if_set(self, lead: str, follow: str, defaulted: Set[str]) -> None:
"""If the value of the lead parameter was set explicitly, apply the value to follow, unless follow was also set explicitly."""
if lead.lower() not in defaulted and follow.lower() in defaulted:
object.__setattr__(self, follow.upper(), getattr(self, lead.upper(), None))
def _assert_mutually_exclusive(
self, params_assigned_from_default: Set[str], group: List[str]
) -> None:
"""
Ensure no elements from group are simultaneously provided by a user, as inferred from params_assigned_from_default.
Raises click.UsageError if any two elements from group are simultaneously provided by a user.
"""
set_flag = None
for flag in group:
flag_set_by_user = flag.lower() not in params_assigned_from_default
if flag_set_by_user and set_flag:
raise DbtUsageException(
f"{flag.lower()}: not allowed with argument {set_flag.lower()}"
)
elif flag_set_by_user:
set_flag = flag
def fire_deprecations(self):
"""Fires events for deprecated env_var usage."""
[dep_fn() for dep_fn in self.deprecated_env_var_warnings]
# It is necessary to remove this attr from the class so it does
# not get pickled when written to disk as json.
object.__delattr__(self, "deprecated_env_var_warnings")

788
core/dbt/cli/main.py Normal file
View File

@@ -0,0 +1,788 @@
import functools
from copy import copy
from dataclasses import dataclass
from typing import Callable, List, Optional, Union
import click
from click.exceptions import (
Exit as ClickExit,
BadOptionUsage,
NoSuchOption,
UsageError,
)
from dbt.cli import requires, params as p
from dbt.cli.exceptions import (
DbtInternalException,
DbtUsageException,
)
from dbt.contracts.graph.manifest import Manifest
from dbt.contracts.results import (
CatalogArtifact,
RunExecutionResult,
RunOperationResultsArtifact,
)
from dbt.events.base_types import EventMsg
from dbt.task.build import BuildTask
from dbt.task.clean import CleanTask
from dbt.task.compile import CompileTask
from dbt.task.debug import DebugTask
from dbt.task.deps import DepsTask
from dbt.task.freshness import FreshnessTask
from dbt.task.generate import GenerateTask
from dbt.task.init import InitTask
from dbt.task.list import ListTask
from dbt.task.run import RunTask
from dbt.task.run_operation import RunOperationTask
from dbt.task.seed import SeedTask
from dbt.task.serve import ServeTask
from dbt.task.show import ShowTask
from dbt.task.snapshot import SnapshotTask
from dbt.task.test import TestTask
@dataclass
class dbtRunnerResult:
"""Contains the result of an invocation of the dbtRunner"""
success: bool
exception: Optional[BaseException] = None
result: Union[
bool, # debug
CatalogArtifact, # docs generate
List[str], # list/ls
Manifest, # parse
None, # clean, deps, init, source
RunExecutionResult, # build, compile, run, seed, snapshot, test
RunOperationResultsArtifact, # run-operation
] = None
# Programmatic invocation
class dbtRunner:
def __init__(
self,
manifest: Manifest = None,
callbacks: List[Callable[[EventMsg], None]] = None,
):
self.manifest = manifest
if callbacks is None:
callbacks = []
self.callbacks = callbacks
def invoke(self, args: List[str], **kwargs) -> dbtRunnerResult:
try:
dbt_ctx = cli.make_context(cli.name, args)
dbt_ctx.obj = {
"manifest": self.manifest,
"callbacks": self.callbacks,
}
for key, value in kwargs.items():
dbt_ctx.params[key] = value
# Hack to set parameter source to custom string
dbt_ctx.set_parameter_source(key, "kwargs") # type: ignore
result, success = cli.invoke(dbt_ctx)
return dbtRunnerResult(
result=result,
success=success,
)
except requires.ResultExit as e:
return dbtRunnerResult(
result=e.result,
success=False,
)
except requires.ExceptionExit as e:
return dbtRunnerResult(
exception=e.exception,
success=False,
)
except (BadOptionUsage, NoSuchOption, UsageError) as e:
return dbtRunnerResult(
exception=DbtUsageException(e.message),
success=False,
)
except ClickExit as e:
if e.exit_code == 0:
return dbtRunnerResult(success=True)
return dbtRunnerResult(
exception=DbtInternalException(f"unhandled exit code {e.exit_code}"),
success=False,
)
except BaseException as e:
return dbtRunnerResult(
exception=e,
success=False,
)
# approach from https://github.com/pallets/click/issues/108#issuecomment-280489786
def global_flags(func):
@p.cache_selected_only
@p.debug
@p.deprecated_print
@p.enable_legacy_logger
@p.fail_fast
@p.log_cache_events
@p.log_file_max_bytes
@p.log_format_file
@p.log_level
@p.log_level_file
@p.log_path
@p.macro_debugging
@p.partial_parse
@p.populate_cache
@p.print
@p.printer_width
@p.quiet
@p.record_timing_info
@p.send_anonymous_usage_stats
@p.single_threaded
@p.static_parser
@p.use_colors
@p.use_colors_file
@p.use_experimental_parser
@p.version
@p.version_check
@p.write_json
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
# dbt
@click.group(
context_settings={"help_option_names": ["-h", "--help"]},
invoke_without_command=True,
no_args_is_help=True,
epilog="Specify one of these sub-commands and you can find more help from there.",
)
@click.pass_context
@global_flags
@p.warn_error
@p.warn_error_options
@p.log_format
def cli(ctx, **kwargs):
"""An ELT tool for managing your SQL transformations and data models.
For more documentation on these commands, visit: docs.getdbt.com
"""
# dbt build
@cli.command("build")
@click.pass_context
@global_flags
@p.defer
@p.deprecated_defer
@p.exclude
@p.favor_state
@p.deprecated_favor_state
@p.full_refresh
@p.indirect_selection
@p.profile
@p.profiles_dir
@p.project_dir
@p.resource_type
@p.select
@p.selector
@p.show
@p.state
@p.deprecated_state
@p.store_failures
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def build(ctx, **kwargs):
"""Run all seeds, models, snapshots, and tests in DAG order"""
task = BuildTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt clean
@cli.command("clean")
@click.pass_context
@global_flags
@p.profile
@p.profiles_dir
@p.project_dir
@p.target
@p.target_path
@p.vars
@requires.postflight
@requires.preflight
@requires.unset_profile
@requires.project
def clean(ctx, **kwargs):
"""Delete all folders in the clean-targets list (usually the dbt_packages and target directories.)"""
task = CleanTask(ctx.obj["flags"], ctx.obj["project"])
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt docs
@cli.group()
@click.pass_context
@global_flags
def docs(ctx, **kwargs):
"""Generate or serve the documentation website for your project"""
# dbt docs generate
@docs.command("generate")
@click.pass_context
@global_flags
@p.compile_docs
@p.defer
@p.deprecated_defer
@p.exclude
@p.favor_state
@p.deprecated_favor_state
@p.profile
@p.profiles_dir
@p.project_dir
@p.select
@p.selector
@p.state
@p.deprecated_state
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest(write=False)
def docs_generate(ctx, **kwargs):
"""Generate the documentation website for your project"""
task = GenerateTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt docs serve
@docs.command("serve")
@click.pass_context
@global_flags
@p.browser
@p.port
@p.profile
@p.profiles_dir
@p.project_dir
@p.target
@p.target_path
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
def docs_serve(ctx, **kwargs):
"""Serve the documentation website for your project"""
task = ServeTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt compile
@cli.command("compile")
@click.pass_context
@global_flags
@p.defer
@p.deprecated_defer
@p.exclude
@p.favor_state
@p.deprecated_favor_state
@p.full_refresh
@p.show_output_format
@p.indirect_selection
@p.introspect
@p.profile
@p.profiles_dir
@p.project_dir
@p.select
@p.selector
@p.inline
@p.state
@p.deprecated_state
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def compile(ctx, **kwargs):
"""Generates executable SQL from source, model, test, and analysis files. Compiled SQL files are written to the
target/ directory."""
task = CompileTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt show
@cli.command("show")
@click.pass_context
@global_flags
@p.defer
@p.deprecated_defer
@p.exclude
@p.favor_state
@p.deprecated_favor_state
@p.full_refresh
@p.show_output_format
@p.show_limit
@p.indirect_selection
@p.introspect
@p.profile
@p.profiles_dir
@p.project_dir
@p.select
@p.selector
@p.inline
@p.state
@p.deprecated_state
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def show(ctx, **kwargs):
"""Generates executable SQL for a named resource or inline query, runs that SQL, and returns a preview of the
results. Does not materialize anything to the warehouse."""
task = ShowTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt debug
@cli.command("debug")
@click.pass_context
@global_flags
@p.config_dir
@p.profile
@p.profiles_dir_exists_false
@p.project_dir
@p.target
@p.vars
@requires.postflight
@requires.preflight
def debug(ctx, **kwargs):
"""Test the database connection and show information for debugging purposes. Not to be confused with the --debug option which increases verbosity."""
task = DebugTask(
ctx.obj["flags"],
None,
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt deps
@cli.command("deps")
@click.pass_context
@global_flags
@p.profile
@p.profiles_dir_exists_false
@p.project_dir
@p.target
@p.vars
@requires.postflight
@requires.preflight
@requires.unset_profile
@requires.project
def deps(ctx, **kwargs):
"""Pull the most recent version of the dependencies listed in packages.yml"""
task = DepsTask(ctx.obj["flags"], ctx.obj["project"])
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt init
@cli.command("init")
@click.pass_context
@global_flags
# for backwards compatibility, accept 'project_name' as an optional positional argument
@click.argument("project_name", required=False)
@p.profile
@p.profiles_dir_exists_false
@p.project_dir
@p.skip_profile_setup
@p.target
@p.vars
@requires.postflight
@requires.preflight
def init(ctx, **kwargs):
"""Initialize a new dbt project."""
task = InitTask(ctx.obj["flags"], None)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt list
@cli.command("list")
@click.pass_context
@global_flags
@p.exclude
@p.indirect_selection
@p.models
@p.output
@p.output_keys
@p.profile
@p.profiles_dir
@p.project_dir
@p.resource_type
@p.raw_select
@p.selector
@p.state
@p.deprecated_state
@p.target
@p.target_path
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def list(ctx, **kwargs):
"""List the resources in your project"""
task = ListTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# Alias "list" to "ls"
ls = copy(cli.commands["list"])
ls.hidden = True
cli.add_command(ls, "ls")
# dbt parse
@cli.command("parse")
@click.pass_context
@global_flags
@p.profile
@p.profiles_dir
@p.project_dir
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest(write_perf_info=True)
def parse(ctx, **kwargs):
"""Parses the project and provides information on performance"""
# manifest generation and writing happens in @requires.manifest
return ctx.obj["manifest"], True
# dbt run
@cli.command("run")
@click.pass_context
@global_flags
@p.defer
@p.deprecated_defer
@p.favor_state
@p.deprecated_favor_state
@p.exclude
@p.full_refresh
@p.profile
@p.profiles_dir
@p.project_dir
@p.select
@p.selector
@p.state
@p.deprecated_state
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def run(ctx, **kwargs):
"""Compile SQL and execute against the current target database."""
task = RunTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt run operation
@cli.command("run-operation")
@click.pass_context
@global_flags
@click.argument("macro")
@p.args
@p.profile
@p.profiles_dir
@p.project_dir
@p.target
@p.target_path
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def run_operation(ctx, **kwargs):
"""Run the named macro with any supplied arguments."""
task = RunOperationTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt seed
@cli.command("seed")
@click.pass_context
@global_flags
@p.exclude
@p.full_refresh
@p.profile
@p.profiles_dir
@p.project_dir
@p.select
@p.selector
@p.show
@p.state
@p.deprecated_state
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def seed(ctx, **kwargs):
"""Load data from csv files into your data warehouse."""
task = SeedTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt snapshot
@cli.command("snapshot")
@click.pass_context
@global_flags
@p.defer
@p.deprecated_defer
@p.exclude
@p.favor_state
@p.deprecated_favor_state
@p.profile
@p.profiles_dir
@p.project_dir
@p.select
@p.selector
@p.state
@p.deprecated_state
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def snapshot(ctx, **kwargs):
"""Execute snapshots defined in your project"""
task = SnapshotTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# dbt source
@cli.group()
@click.pass_context
@global_flags
def source(ctx, **kwargs):
"""Manage your project's sources"""
# dbt source freshness
@source.command("freshness")
@click.pass_context
@global_flags
@p.exclude
@p.output_path # TODO: Is this ok to re-use? We have three different output params, how much can we consolidate?
@p.profile
@p.profiles_dir
@p.project_dir
@p.select
@p.selector
@p.state
@p.deprecated_state
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def freshness(ctx, **kwargs):
"""check the current freshness of the project's sources"""
task = FreshnessTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# Alias "source freshness" to "snapshot-freshness"
snapshot_freshness = copy(cli.commands["source"].commands["freshness"]) # type: ignore
snapshot_freshness.hidden = True
cli.commands["source"].add_command(snapshot_freshness, "snapshot-freshness") # type: ignore
# dbt test
@cli.command("test")
@click.pass_context
@global_flags
@p.defer
@p.deprecated_defer
@p.exclude
@p.favor_state
@p.deprecated_favor_state
@p.indirect_selection
@p.profile
@p.profiles_dir
@p.project_dir
@p.select
@p.selector
@p.state
@p.deprecated_state
@p.store_failures
@p.target
@p.target_path
@p.threads
@p.vars
@requires.postflight
@requires.preflight
@requires.profile
@requires.project
@requires.runtime_config
@requires.manifest
def test(ctx, **kwargs):
"""Runs tests on data in deployed models. Run this after `dbt run`"""
task = TestTask(
ctx.obj["flags"],
ctx.obj["runtime_config"],
ctx.obj["manifest"],
)
results = task.run()
success = task.interpret_results(results)
return results, success
# Support running as a module
if __name__ == "__main__":
cli()

View File

@@ -0,0 +1,62 @@
from click import ParamType, Choice
from dbt.config.utils import parse_cli_yaml_string
from dbt.exceptions import ValidationError, DbtValidationError, OptionNotYamlDictError
from dbt.helper_types import WarnErrorOptions
class YAML(ParamType):
"""The Click YAML type. Converts YAML strings into objects."""
name = "YAML"
def convert(self, value, param, ctx):
# assume non-string values are a problem
if not isinstance(value, str):
self.fail(f"Cannot load YAML from type {type(value)}", param, ctx)
try:
param_option_name = param.opts[0] if param.opts else param.name
return parse_cli_yaml_string(value, param_option_name.strip("-"))
except (ValidationError, DbtValidationError, OptionNotYamlDictError):
self.fail(f"String '{value}' is not valid YAML", param, ctx)
class WarnErrorOptionsType(YAML):
"""The Click WarnErrorOptions type. Converts YAML strings into objects."""
name = "WarnErrorOptionsType"
def convert(self, value, param, ctx):
# this function is being used by param in click
include_exclude = super().convert(value, param, ctx)
return WarnErrorOptions(
include=include_exclude.get("include", []), exclude=include_exclude.get("exclude", [])
)
class Truthy(ParamType):
"""The Click Truthy type. Converts strings into a "truthy" type"""
name = "TRUTHY"
def convert(self, value, param, ctx):
# assume non-string / non-None values are a problem
if not isinstance(value, (str, None)):
self.fail(f"Cannot load TRUTHY from type {type(value)}", param, ctx)
if value is None or value.lower() in ("0", "false", "f"):
return None
else:
return value
class ChoiceTuple(Choice):
name = "CHOICE_TUPLE"
def convert(self, value, param, ctx):
for value_item in value:
super().convert(value_item, param, ctx)
return value

78
core/dbt/cli/options.py Normal file
View File

@@ -0,0 +1,78 @@
import click
import inspect
import typing as t
from click import Context
from click.parser import OptionParser, ParsingState
from dbt.cli.option_types import ChoiceTuple
# Implementation from: https://stackoverflow.com/a/48394004
# Note MultiOption options must be specified with type=tuple or type=ChoiceTuple (https://github.com/pallets/click/issues/2012)
class MultiOption(click.Option):
def __init__(self, *args, **kwargs):
self.save_other_options = kwargs.pop("save_other_options", True)
nargs = kwargs.pop("nargs", -1)
assert nargs == -1, "nargs, if set, must be -1 not {}".format(nargs)
super(MultiOption, self).__init__(*args, **kwargs)
# this makes mypy happy, setting these to None causes mypy failures
self._previous_parser_process = lambda *args, **kwargs: None
self._eat_all_parser = lambda *args, **kwargs: None
# validate that multiple=True
multiple = kwargs.pop("multiple", None)
msg = f"MultiOption named `{self.name}` must have multiple=True (rather than {multiple})"
assert multiple, msg
# validate that type=tuple or type=ChoiceTuple
option_type = kwargs.pop("type", None)
msg = f"MultiOption named `{self.name}` must be tuple or ChoiceTuple (rather than {option_type})"
if inspect.isclass(option_type):
assert issubclass(option_type, tuple), msg
else:
assert isinstance(option_type, ChoiceTuple), msg
def add_to_parser(self, parser: OptionParser, ctx: Context):
def parser_process(value: str, state: ParsingState):
# method to hook to the parser.process
done = False
value_list = str.split(value, " ")
if self.save_other_options:
# grab everything up to the next option
while state.rargs and not done:
for prefix in self._eat_all_parser.prefixes: # type: ignore[attr-defined]
if state.rargs[0].startswith(prefix):
done = True
if not done:
value_list.append(state.rargs.pop(0))
else:
# grab everything remaining
value_list += state.rargs
state.rargs[:] = []
value_tuple = tuple(value_list)
# call the actual process
self._previous_parser_process(value_tuple, state)
retval = super(MultiOption, self).add_to_parser(parser, ctx)
for name in self.opts:
our_parser = parser._long_opt.get(name) or parser._short_opt.get(name)
if our_parser:
self._eat_all_parser = our_parser # type: ignore[assignment]
self._previous_parser_process = our_parser.process
# mypy doesnt like assingment to a method see https://github.com/python/mypy/issues/708
our_parser.process = parser_process # type: ignore[assignment]
break
return retval
def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any:
def flatten(data):
if isinstance(data, tuple):
for x in data:
yield from flatten(x)
else:
yield data
# there will be nested tuples to flatten when multiple=True
value = super(MultiOption, self).type_cast_value(ctx, value)
if value:
value = tuple(flatten(value))
return value

556
core/dbt/cli/params.py Normal file
View File

@@ -0,0 +1,556 @@
from pathlib import Path
import click
from dbt.cli.options import MultiOption
from dbt.cli.option_types import YAML, ChoiceTuple, WarnErrorOptionsType
from dbt.cli.resolvers import default_project_dir, default_profiles_dir
from dbt.version import get_version_information
args = click.option(
"--args",
envvar=None,
help="Supply arguments to the macro. This dictionary will be mapped to the keyword arguments defined in the selected macro. This argument should be a YAML string, eg. '{my_variable: my_value}'",
type=YAML(),
)
browser = click.option(
"--browser/--no-browser",
envvar=None,
help="Wether or not to open a local web browser after starting the server",
default=True,
)
cache_selected_only = click.option(
"--cache-selected-only/--no-cache-selected-only",
envvar="DBT_CACHE_SELECTED_ONLY",
help="At start of run, populate relational cache only for schemas containing selected nodes, or for all schemas of interest.",
)
introspect = click.option(
"--introspect/--no-introspect",
envvar="DBT_INTROSPECT",
help="Whether to scaffold introspective queries as part of compilation",
default=True,
)
compile_docs = click.option(
"--compile/--no-compile",
envvar=None,
help="Whether or not to run 'dbt compile' as part of docs generation",
default=True,
)
config_dir = click.option(
"--config-dir",
envvar=None,
help="Show the configured location for the profiles.yml file and exit",
is_flag=True,
)
debug = click.option(
"--debug/--no-debug",
"-d/ ",
envvar="DBT_DEBUG",
help="Display debug logging during dbt execution. Useful for debugging and making bug reports.",
)
# flag was previously named DEFER_MODE
defer = click.option(
"--defer/--no-defer",
envvar="DBT_DEFER",
help="If set, resolve unselected nodes by deferring to the manifest within the --state directory.",
)
deprecated_defer = click.option(
"--deprecated-defer",
envvar="DBT_DEFER_TO_STATE",
help="Internal flag for deprecating old env var.",
default=False,
hidden=True,
)
enable_legacy_logger = click.option(
"--enable-legacy-logger/--no-enable-legacy-logger",
envvar="DBT_ENABLE_LEGACY_LOGGER",
hidden=True,
)
exclude = click.option(
"--exclude",
envvar=None,
type=tuple,
cls=MultiOption,
multiple=True,
help="Specify the nodes to exclude.",
)
fail_fast = click.option(
"--fail-fast/--no-fail-fast",
"-x/ ",
envvar="DBT_FAIL_FAST",
help="Stop execution on first failure.",
)
favor_state = click.option(
"--favor-state/--no-favor-state",
envvar="DBT_FAVOR_STATE",
help="If set, defer to the argument provided to the state flag for resolving unselected nodes, even if the node(s) exist as a database object in the current environment.",
)
deprecated_favor_state = click.option(
"--deprecated-favor-state",
envvar="DBT_FAVOR_STATE_MODE",
help="Internal flag for deprecating old env var.",
)
full_refresh = click.option(
"--full-refresh",
"-f",
envvar="DBT_FULL_REFRESH",
help="If specified, dbt will drop incremental models and fully-recalculate the incremental table from the model definition.",
is_flag=True,
)
indirect_selection = click.option(
"--indirect-selection",
envvar="DBT_INDIRECT_SELECTION",
help="Choose which tests to select that are adjacent to selected resources. Eager is most inclusive, cautious is most exclusive, and buildable is in between. Empty includes no tests at all.",
type=click.Choice(["eager", "cautious", "buildable", "empty"], case_sensitive=False),
default="eager",
)
log_cache_events = click.option(
"--log-cache-events/--no-log-cache-events",
help="Enable verbose logging for relational cache events to help when debugging.",
envvar="DBT_LOG_CACHE_EVENTS",
)
log_format = click.option(
"--log-format",
envvar="DBT_LOG_FORMAT",
help="Specify the format of logging to the console and the log file. Use --log-format-file to configure the format for the log file differently than the console.",
type=click.Choice(["text", "debug", "json", "default"], case_sensitive=False),
default="default",
)
log_format_file = click.option(
"--log-format-file",
envvar="DBT_LOG_FORMAT_FILE",
help="Specify the format of logging to the log file by overriding the default value and the general --log-format setting.",
type=click.Choice(["text", "debug", "json", "default"], case_sensitive=False),
default="debug",
)
log_level = click.option(
"--log-level",
envvar="DBT_LOG_LEVEL",
help="Specify the minimum severity of events that are logged to the console and the log file. Use --log-level-file to configure the severity for the log file differently than the console.",
type=click.Choice(["debug", "info", "warn", "error", "none"], case_sensitive=False),
default="info",
)
log_level_file = click.option(
"--log-level-file",
envvar="DBT_LOG_LEVEL_FILE",
help="Specify the minimum severity of events that are logged to the log file by overriding the default value and the general --log-level setting.",
type=click.Choice(["debug", "info", "warn", "error", "none"], case_sensitive=False),
default="debug",
)
use_colors = click.option(
"--use-colors/--no-use-colors",
envvar="DBT_USE_COLORS",
help="Specify whether log output is colorized in the console and the log file. Use --use-colors-file/--no-use-colors-file to colorize the log file differently than the console.",
default=True,
)
use_colors_file = click.option(
"--use-colors-file/--no-use-colors-file",
envvar="DBT_USE_COLORS_FILE",
help="Specify whether log file output is colorized by overriding the default value and the general --use-colors/--no-use-colors setting.",
default=True,
)
log_file_max_bytes = click.option(
"--log-file-max-bytes",
envvar="DBT_LOG_FILE_MAX_BYTES",
help="Configure the max file size in bytes for a single dbt.log file, before rolling over. 0 means no limit.",
default=10 * 1024 * 1024, # 10mb
type=click.INT,
hidden=True,
)
log_path = click.option(
"--log-path",
envvar="DBT_LOG_PATH",
help="Configure the 'log-path'. Only applies this setting for the current run. Overrides the 'DBT_LOG_PATH' if it is set.",
default=None,
type=click.Path(resolve_path=True, path_type=Path),
)
macro_debugging = click.option(
"--macro-debugging/--no-macro-debugging",
envvar="DBT_MACRO_DEBUGGING",
hidden=True,
)
# This less standard usage of --output where output_path below is more standard
output = click.option(
"--output",
envvar=None,
help="Specify the output format: either JSON or a newline-delimited list of selectors, paths, or names",
type=click.Choice(["json", "name", "path", "selector"], case_sensitive=False),
default="selector",
)
show_output_format = click.option(
"--output",
envvar=None,
help="Output format for dbt compile and dbt show",
type=click.Choice(["json", "text"], case_sensitive=False),
default="text",
)
show_limit = click.option(
"--limit",
envvar=None,
help="Limit the number of results returned by dbt show",
type=click.INT,
default=5,
)
output_keys = click.option(
"--output-keys",
envvar=None,
help=(
"Space-delimited listing of node properties to include as custom keys for JSON output "
"(e.g. `--output json --output-keys name resource_type description`)"
),
type=tuple,
cls=MultiOption,
multiple=True,
default=[],
)
output_path = click.option(
"--output",
"-o",
envvar=None,
help="Specify the output path for the JSON report. By default, outputs to 'target/sources.json'",
type=click.Path(file_okay=True, dir_okay=False, writable=True),
default=None,
)
partial_parse = click.option(
"--partial-parse/--no-partial-parse",
envvar="DBT_PARTIAL_PARSE",
help="Allow for partial parsing by looking for and writing to a pickle file in the target directory. This overrides the user configuration file.",
default=True,
)
populate_cache = click.option(
"--populate-cache/--no-populate-cache",
envvar="DBT_POPULATE_CACHE",
help="At start of run, use `show` or `information_schema` queries to populate a relational cache, which can speed up subsequent materializations.",
default=True,
)
port = click.option(
"--port",
envvar=None,
help="Specify the port number for the docs server",
default=8080,
type=click.INT,
)
print = click.option(
"--print/--no-print",
envvar="DBT_PRINT",
help="Output all {{ print() }} macro calls.",
default=True,
)
deprecated_print = click.option(
"--deprecated-print/--deprecated-no-print",
envvar="DBT_NO_PRINT",
help="Internal flag for deprecating old env var.",
default=True,
hidden=True,
callback=lambda ctx, param, value: not value,
)
printer_width = click.option(
"--printer-width",
envvar="DBT_PRINTER_WIDTH",
help="Sets the width of terminal output",
type=click.INT,
default=80,
)
profile = click.option(
"--profile",
envvar=None,
help="Which profile to load. Overrides setting in dbt_project.yml.",
)
profiles_dir = click.option(
"--profiles-dir",
envvar="DBT_PROFILES_DIR",
help="Which directory to look in for the profiles.yml file. If not set, dbt will look in the current working directory first, then HOME/.dbt/",
default=default_profiles_dir,
type=click.Path(exists=True),
)
# `dbt debug` uses this because it implements custom behaviour for non-existent profiles.yml directories
# `dbt deps` does not load a profile at all
# `dbt init` will write profiles.yml if it doesn't yet exist
profiles_dir_exists_false = click.option(
"--profiles-dir",
envvar="DBT_PROFILES_DIR",
help="Which directory to look in for the profiles.yml file. If not set, dbt will look in the current working directory first, then HOME/.dbt/",
default=default_profiles_dir,
type=click.Path(exists=False),
)
project_dir = click.option(
"--project-dir",
envvar="DBT_PROJECT_DIR",
help="Which directory to look in for the dbt_project.yml file. Default is the current working directory and its parents.",
default=default_project_dir,
type=click.Path(exists=True),
)
quiet = click.option(
"--quiet/--no-quiet",
"-q",
envvar="DBT_QUIET",
help="Suppress all non-error logging to stdout. Does not affect {{ print() }} macro calls.",
)
record_timing_info = click.option(
"--record-timing-info",
"-r",
envvar=None,
help="When this option is passed, dbt will output low-level timing stats to the specified file. Example: `--record-timing-info output.profile`",
type=click.Path(exists=False),
)
resource_type = click.option(
"--resource-types",
"--resource-type",
envvar=None,
help="Restricts the types of resources that dbt will include",
type=ChoiceTuple(
[
"metric",
"source",
"analysis",
"model",
"test",
"exposure",
"snapshot",
"seed",
"default",
"all",
],
case_sensitive=False,
),
cls=MultiOption,
multiple=True,
default=(),
)
model_decls = ("-m", "--models", "--model")
select_decls = ("-s", "--select")
select_attrs = {
"envvar": None,
"help": "Specify the nodes to include.",
"cls": MultiOption,
"multiple": True,
"type": tuple,
}
inline = click.option(
"--inline",
envvar=None,
help="Pass SQL inline to dbt compile and show",
)
# `--select` and `--models` are analogous for most commands except `dbt list` for legacy reasons.
# Most CLI arguments should use the combined `select` option that aliases `--models` to `--select`.
# However, if you need to split out these separators (like `dbt ls`), use the `models` and `raw_select` options instead.
# See https://github.com/dbt-labs/dbt-core/pull/6774#issuecomment-1408476095 for more info.
models = click.option(*model_decls, **select_attrs) # type: ignore[arg-type]
raw_select = click.option(*select_decls, **select_attrs) # type: ignore[arg-type]
select = click.option(*select_decls, *model_decls, **select_attrs) # type: ignore[arg-type]
selector = click.option(
"--selector",
envvar=None,
help="The selector name to use, as defined in selectors.yml",
)
send_anonymous_usage_stats = click.option(
"--send-anonymous-usage-stats/--no-send-anonymous-usage-stats",
envvar="DBT_SEND_ANONYMOUS_USAGE_STATS",
help="Send anonymous usage stats to dbt Labs.",
default=True,
)
show = click.option(
"--show",
envvar=None,
help="Show a sample of the loaded data in the terminal",
is_flag=True,
)
# TODO: The env var is a correction!
# The original env var was `DBT_TEST_SINGLE_THREADED`.
# This broke the existing naming convention.
# This will need to be communicated as a change to the community!
#
# N.B. This flag is only used for testing, hence it's hidden from help text.
single_threaded = click.option(
"--single-threaded/--no-single-threaded",
envvar="DBT_SINGLE_THREADED",
default=False,
hidden=True,
)
skip_profile_setup = click.option(
"--skip-profile-setup",
"-s",
envvar=None,
help="Skip interactive profile setup.",
is_flag=True,
)
state = click.option(
"--state",
envvar="DBT_STATE",
help="If set, use the given directory as the source for JSON files to compare with this project.",
type=click.Path(
dir_okay=True,
file_okay=False,
readable=True,
resolve_path=False,
path_type=Path,
),
)
deprecated_state = click.option(
"--deprecated-state",
envvar="DBT_ARTIFACT_STATE_PATH",
help="Internal flag for deprecating old env var.",
hidden=True,
type=click.Path(
dir_okay=True,
file_okay=False,
readable=True,
resolve_path=True,
path_type=Path,
),
)
static_parser = click.option(
"--static-parser/--no-static-parser",
envvar="DBT_STATIC_PARSER",
help="Use the static parser.",
default=True,
)
store_failures = click.option(
"--store-failures",
envvar="DBT_STORE_FAILURES",
help="Store test results (failing rows) in the database",
is_flag=True,
)
target = click.option(
"--target",
"-t",
envvar=None,
help="Which target to load for the given profile",
)
target_path = click.option(
"--target-path",
envvar="DBT_TARGET_PATH",
help="Configure the 'target-path'. Only applies this setting for the current run. Overrides the 'DBT_TARGET_PATH' if it is set.",
type=click.Path(),
)
threads = click.option(
"--threads",
envvar=None,
help="Specify number of threads to use while executing models. Overrides settings in profiles.yml.",
default=None,
type=click.INT,
)
use_experimental_parser = click.option(
"--use-experimental-parser/--no-use-experimental-parser",
envvar="DBT_USE_EXPERIMENTAL_PARSER",
help="Enable experimental parsing features.",
)
vars = click.option(
"--vars",
envvar=None,
help="Supply variables to the project. This argument overrides variables defined in your dbt_project.yml file. This argument should be a YAML string, eg. '{my_variable: my_value}'",
type=YAML(),
default="{}",
)
# TODO: when legacy flags are deprecated use
# click.version_option instead of a callback
def _version_callback(ctx, _param, value):
if not value or ctx.resilient_parsing:
return
click.echo(get_version_information())
ctx.exit()
version = click.option(
"--version",
"-V",
"-v",
callback=_version_callback,
envvar=None,
expose_value=False,
help="Show version information and exit",
is_eager=True,
is_flag=True,
)
version_check = click.option(
"--version-check/--no-version-check",
envvar="DBT_VERSION_CHECK",
help="If set, ensure the installed dbt version matches the require-dbt-version specified in the dbt_project.yml file (if any). Otherwise, allow them to differ.",
default=True,
)
warn_error = click.option(
"--warn-error",
envvar="DBT_WARN_ERROR",
help="If dbt would normally warn, instead raise an exception. Examples include --select that selects nothing, deprecations, configurations with no associated models, invalid test configurations, and missing sources/refs in tests.",
default=None,
is_flag=True,
)
warn_error_options = click.option(
"--warn-error-options",
envvar="DBT_WARN_ERROR_OPTIONS",
default="{}",
help="""If dbt would normally warn, instead raise an exception based on include/exclude configuration. Examples include --select that selects nothing, deprecations, configurations with no associated models, invalid test configurations,
and missing sources/refs in tests. This argument should be a YAML string, with keys 'include' or 'exclude'. eg. '{"include": "all", "exclude": ["NoNodesForSelectionCriteria"]}'""",
type=WarnErrorOptionsType(),
)
write_json = click.option(
"--write-json/--no-write-json",
envvar="DBT_WRITE_JSON",
help="Whether or not to write the manifest.json and run_results.json files to the target directory",
default=True,
)

258
core/dbt/cli/requires.py Normal file
View File

@@ -0,0 +1,258 @@
import dbt.tracking
from dbt.version import installed as installed_version
from dbt.adapters.factory import adapter_management, register_adapter
from dbt.flags import set_flags, get_flag_dict
from dbt.cli.exceptions import (
ExceptionExit,
ResultExit,
)
from dbt.cli.flags import Flags
from dbt.config import RuntimeConfig
from dbt.config.runtime import load_project, load_profile, UnsetProfile
from dbt.events.functions import fire_event, LOG_VERSION, set_invocation_id, setup_event_logger
from dbt.events.types import (
CommandCompleted,
MainReportVersion,
MainReportArgs,
MainTrackingUserState,
)
from dbt.events.helpers import get_json_string_utcnow
from dbt.events.types import MainEncounteredError, MainStackTrace
from dbt.exceptions import Exception as DbtException, DbtProjectError, FailFastError
from dbt.parser.manifest import ManifestLoader, write_manifest
from dbt.profiler import profiler
from dbt.tracking import active_user, initialize_from_flags, track_run
from dbt.utils import cast_dict_to_dict_of_strings
from click import Context
from functools import update_wrapper
import time
import traceback
def preflight(func):
def wrapper(*args, **kwargs):
ctx = args[0]
assert isinstance(ctx, Context)
ctx.obj = ctx.obj or {}
# Flags
flags = Flags(ctx)
ctx.obj["flags"] = flags
set_flags(flags)
# Logging
callbacks = ctx.obj.get("callbacks", [])
set_invocation_id()
setup_event_logger(flags=flags, callbacks=callbacks)
# Tracking
initialize_from_flags(flags.SEND_ANONYMOUS_USAGE_STATS, flags.PROFILES_DIR)
ctx.with_resource(track_run(run_command=flags.WHICH))
# Now that we have our logger, fire away!
fire_event(MainReportVersion(version=str(installed_version), log_version=LOG_VERSION))
flags_dict_str = cast_dict_to_dict_of_strings(get_flag_dict())
fire_event(MainReportArgs(args=flags_dict_str))
# Deprecation warnings
flags.fire_deprecations()
if active_user is not None: # mypy appeasement, always true
fire_event(MainTrackingUserState(user_state=active_user.state()))
# Profiling
if flags.RECORD_TIMING_INFO:
ctx.with_resource(profiler(enable=True, outfile=flags.RECORD_TIMING_INFO))
# Adapter management
ctx.with_resource(adapter_management())
return func(*args, **kwargs)
return update_wrapper(wrapper, func)
def postflight(func):
"""The decorator that handles all exception handling for the click commands.
This decorator must be used before any other decorators that may throw an exception."""
def wrapper(*args, **kwargs):
ctx = args[0]
start_func = time.perf_counter()
success = False
try:
result, success = func(*args, **kwargs)
except FailFastError as e:
fire_event(MainEncounteredError(exc=str(e)))
raise ResultExit(e.result)
except DbtException as e:
fire_event(MainEncounteredError(exc=str(e)))
raise ExceptionExit(e)
except BaseException as e:
fire_event(MainEncounteredError(exc=str(e)))
fire_event(MainStackTrace(stack_trace=traceback.format_exc()))
raise ExceptionExit(e)
finally:
fire_event(
CommandCompleted(
command=ctx.command_path,
success=success,
completed_at=get_json_string_utcnow(),
elapsed=time.perf_counter() - start_func,
)
)
if not success:
raise ResultExit(result)
return (result, success)
return update_wrapper(wrapper, func)
# TODO: UnsetProfile is necessary for deps and clean to load a project.
# This decorator and its usage can be removed once https://github.com/dbt-labs/dbt-core/issues/6257 is closed.
def unset_profile(func):
def wrapper(*args, **kwargs):
ctx = args[0]
assert isinstance(ctx, Context)
profile = UnsetProfile()
ctx.obj["profile"] = profile
return func(*args, **kwargs)
return update_wrapper(wrapper, func)
def profile(func):
def wrapper(*args, **kwargs):
ctx = args[0]
assert isinstance(ctx, Context)
flags = ctx.obj["flags"]
# TODO: Generalize safe access to flags.THREADS:
# https://github.com/dbt-labs/dbt-core/issues/6259
threads = getattr(flags, "THREADS", None)
profile = load_profile(flags.PROJECT_DIR, flags.VARS, flags.PROFILE, flags.TARGET, threads)
ctx.obj["profile"] = profile
return func(*args, **kwargs)
return update_wrapper(wrapper, func)
def project(func):
def wrapper(*args, **kwargs):
ctx = args[0]
assert isinstance(ctx, Context)
# TODO: Decouple target from profile, and remove the need for profile here:
# https://github.com/dbt-labs/dbt-core/issues/6257
if not ctx.obj.get("profile"):
raise DbtProjectError("profile required for project")
flags = ctx.obj["flags"]
project = load_project(
flags.PROJECT_DIR, flags.VERSION_CHECK, ctx.obj["profile"], flags.VARS
)
ctx.obj["project"] = project
if dbt.tracking.active_user is not None:
project_id = None if project is None else project.hashed_name()
dbt.tracking.track_project_id({"project_id": project_id})
return func(*args, **kwargs)
return update_wrapper(wrapper, func)
def runtime_config(func):
"""A decorator used by click command functions for generating a runtime
config given a profile and project.
"""
def wrapper(*args, **kwargs):
ctx = args[0]
assert isinstance(ctx, Context)
req_strs = ["profile", "project"]
reqs = [ctx.obj.get(req_str) for req_str in req_strs]
if None in reqs:
raise DbtProjectError("profile and project required for runtime_config")
config = RuntimeConfig.from_parts(
ctx.obj["project"],
ctx.obj["profile"],
ctx.obj["flags"],
)
ctx.obj["runtime_config"] = config
if dbt.tracking.active_user is not None:
adapter_type = (
getattr(config.credentials, "type", None)
if hasattr(config, "credentials")
else None
)
adapter_unique_id = (
config.credentials.hashed_unique_field()
if hasattr(config, "credentials")
else None
)
dbt.tracking.track_adapter_info(
{
"adapter_type": adapter_type,
"adapter_unique_id": adapter_unique_id,
}
)
return func(*args, **kwargs)
return update_wrapper(wrapper, func)
def manifest(*args0, write=True, write_perf_info=False):
"""A decorator used by click command functions for generating a manifest
given a profile, project, and runtime config. This also registers the adapter
from the runtime config and conditionally writes the manifest to disk.
"""
def outer_wrapper(func):
def wrapper(*args, **kwargs):
ctx = args[0]
assert isinstance(ctx, Context)
req_strs = ["profile", "project", "runtime_config"]
reqs = [ctx.obj.get(dep) for dep in req_strs]
if None in reqs:
raise DbtProjectError("profile, project, and runtime_config required for manifest")
runtime_config = ctx.obj["runtime_config"]
register_adapter(runtime_config)
# a manifest has already been set on the context, so don't overwrite it
if ctx.obj.get("manifest") is None:
manifest = ManifestLoader.get_full_manifest(
runtime_config, write_perf_info=write_perf_info
)
ctx.obj["manifest"] = manifest
if write and ctx.obj["flags"].write_json:
write_manifest(manifest, ctx.obj["runtime_config"].project_target_path)
return func(*args, **kwargs)
return update_wrapper(wrapper, func)
# if there are no args, the decorator was used without params @decorator
# otherwise, the decorator was called with params @decorator(arg)
if len(args0) == 0:
return outer_wrapper
return outer_wrapper(args0[0])

31
core/dbt/cli/resolvers.py Normal file
View File

@@ -0,0 +1,31 @@
from pathlib import Path
from dbt.config.project import PartialProject
from dbt.exceptions import DbtProjectError
def default_project_dir() -> Path:
paths = list(Path.cwd().parents)
paths.insert(0, Path.cwd())
return next((x for x in paths if (x / "dbt_project.yml").exists()), Path.cwd())
def default_profiles_dir() -> Path:
return Path.cwd() if (Path.cwd() / "profiles.yml").exists() else Path.home() / ".dbt"
def default_log_path(project_dir: Path, verify_version: bool = False) -> Path:
"""If available, derive a default log path from dbt_project.yml. Otherwise, default to "logs".
Known limitations:
1. Using PartialProject here, so no jinja rendering of log-path.
2. Programmatic invocations of the cli via dbtRunner may pass a Project object directly,
which is not being taken into consideration here to extract a log-path.
"""
default_log_path = Path("logs")
try:
partial = PartialProject.from_project_root(str(project_dir), verify_version=verify_version)
partial_log_path = partial.project_dict.get("log-path") or default_log_path
default_log_path = Path(project_dir) / partial_log_path
except DbtProjectError:
pass
return default_log_path

View File

@@ -1 +1,19 @@
# Clients README
### Jinja
#### How are materializations defined
Model materializations are kept in `core/dbt/include/global_project/macros/materializations/models/`. Materializations are defined using syntax that isn't part of the Jinja standard library. These tags are referenced internally, and materializations can be overridden in user projects when users have specific needs.
```
-- Pseudocode for arguments
{% materialization <name>, <target name := one_of{default, adapter}> %}'
{% endmaterialization %}
```
These blocks are referred to Jinja extensions. Extensions are defined as part of the accepted Jinja code encapsulated within a dbt project. This includes system code used internally by dbt and user space (i.e. user-defined) macros. Extensions exist to help Jinja users create reusable code blocks or abstract objects--for us, materializations are a great use-case since we pass these around as arguments within dbt system code.
The code that defines this extension is a class `MaterializationExtension` and a `parse` routine. That code lives in [clients/jinja.py](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/clients/jinja.py). The routine
enables Jinja to parse (i.e. recognize) the unique comma separated arg structure our `materialization` tags exhibit (the `table, default` as seen above).

View File

@@ -1,7 +1,15 @@
import re
from collections import namedtuple
import dbt.exceptions
from dbt.exceptions import (
BlockDefinitionNotAtTopError,
DbtInternalError,
MissingCloseTagError,
MissingControlFlowStartTagError,
NestedTagsError,
UnexpectedControlFlowEndTagError,
UnexpectedMacroEOFError,
)
def regex(pat):
@@ -139,10 +147,7 @@ class TagIterator:
def _expect_match(self, expected_name, *patterns, **kwargs):
match = self._first_match(*patterns, **kwargs)
if match is None:
msg = 'unexpected EOF, expected {}, got "{}"'.format(
expected_name, self.data[self.pos :]
)
dbt.exceptions.raise_compiler_error(msg)
raise UnexpectedMacroEOFError(expected_name, self.data[self.pos :])
return match
def handle_expr(self, match):
@@ -256,7 +261,7 @@ class TagIterator:
elif block_type_name is not None:
yield self.handle_tag(match)
else:
raise dbt.exceptions.InternalException(
raise DbtInternalError(
"Invalid regex match in next_block, expected block start, "
"expr start, or comment start"
)
@@ -265,13 +270,6 @@ class TagIterator:
return self.find_tags()
duplicate_tags = (
"Got nested tags: {outer.block_type_name} (started at {outer.start}) did "
"not have a matching {{% end{outer.block_type_name} %}} before a "
"subsequent {inner.block_type_name} was found (started at {inner.start})"
)
_CONTROL_FLOW_TAGS = {
"if": "endif",
"for": "endfor",
@@ -319,33 +317,16 @@ class BlockIterator:
found = self.stack.pop()
else:
expected = _CONTROL_FLOW_END_TAGS[tag.block_type_name]
dbt.exceptions.raise_compiler_error(
(
"Got an unexpected control flow end tag, got {} but "
"never saw a preceeding {} (@ {})"
).format(tag.block_type_name, expected, self.tag_parser.linepos(tag.start))
)
raise UnexpectedControlFlowEndTagError(tag, expected, self.tag_parser)
expected = _CONTROL_FLOW_TAGS[found]
if expected != tag.block_type_name:
dbt.exceptions.raise_compiler_error(
(
"Got an unexpected control flow end tag, got {} but "
"expected {} next (@ {})"
).format(tag.block_type_name, expected, self.tag_parser.linepos(tag.start))
)
raise MissingControlFlowStartTagError(tag, expected, self.tag_parser)
if tag.block_type_name in allowed_blocks:
if self.stack:
dbt.exceptions.raise_compiler_error(
(
"Got a block definition inside control flow at {}. "
"All dbt block definitions must be at the top level"
).format(self.tag_parser.linepos(tag.start))
)
raise BlockDefinitionNotAtTopError(self.tag_parser, tag.start)
if self.current is not None:
dbt.exceptions.raise_compiler_error(
duplicate_tags.format(outer=self.current, inner=tag)
)
raise NestedTagsError(outer=self.current, inner=tag)
if collect_raw_data:
raw_data = self.data[self.last_position : tag.start]
self.last_position = tag.start
@@ -366,11 +347,7 @@ class BlockIterator:
if self.current:
linecount = self.data[: self.current.end].count("\n") + 1
dbt.exceptions.raise_compiler_error(
(
"Reached EOF without finding a close tag for " "{} (searched from line {})"
).format(self.current.block_type_name, linecount)
)
raise MissingCloseTagError(self.current.block_type_name, linecount)
if collect_raw_data:
raw_data = self.data[self.last_position :]

View File

@@ -7,7 +7,7 @@ import json
import dbt.utils
from typing import Iterable, List, Dict, Union, Optional, Any
from dbt.exceptions import RuntimeException
from dbt.exceptions import DbtRuntimeError
BOM = BOM_UTF8.decode("utf-8") # '\ufeff'
@@ -80,7 +80,7 @@ def table_from_rows(
def table_from_data(data, column_names: Iterable[str]) -> agate.Table:
"Convert list of dictionaries into an Agate table"
"Convert a list of dictionaries into an Agate table"
# The agate table is generated from a list of dicts, so the column order
# from `data` is not preserved. We can use `select` to reorder the columns
@@ -168,7 +168,7 @@ class ColumnTypeBuilder(Dict[str, NullableAgateType]):
return
elif not isinstance(value, type(existing_type)):
# actual type mismatch!
raise RuntimeException(
raise DbtRuntimeError(
f"Tables contain columns with the same names ({key}), "
f"but different types ({value} vs {existing_type})"
)

View File

@@ -14,10 +14,10 @@ from dbt.events.types import (
)
from dbt.exceptions import (
CommandResultError,
RuntimeException,
bad_package_spec,
raise_git_cloning_error,
raise_git_cloning_problem,
GitCheckoutError,
GitCloningError,
UnknownGitCloningProblemError,
DbtRuntimeError,
)
from packaging import version
@@ -27,16 +27,6 @@ def _is_commit(revision: str) -> bool:
return bool(re.match(r"\b[0-9a-f]{40}\b", revision))
def _raise_git_cloning_error(repo, revision, error):
stderr = error.stderr.decode("utf-8").strip()
if "usage: git" in stderr:
stderr = stderr.split("\nusage: git")[0]
if re.match("fatal: destination path '(.+)' already exists", stderr):
raise_git_cloning_error(error)
bad_package_spec(repo, revision, stderr)
def clone(repo, cwd, dirname=None, remove_git_dir=False, revision=None, subdirectory=None):
has_revision = revision is not None
is_commit = _is_commit(revision or "")
@@ -64,7 +54,7 @@ def clone(repo, cwd, dirname=None, remove_git_dir=False, revision=None, subdirec
try:
result = run_cmd(cwd, clone_cmd, env={"LC_ALL": "C"})
except CommandResultError as exc:
_raise_git_cloning_error(repo, revision, exc)
raise GitCloningError(repo, revision, exc)
if subdirectory:
cwd_subdir = os.path.join(cwd, dirname or "")
@@ -72,7 +62,7 @@ def clone(repo, cwd, dirname=None, remove_git_dir=False, revision=None, subdirec
try:
run_cmd(cwd_subdir, clone_cmd_subdir)
except CommandResultError as exc:
_raise_git_cloning_error(repo, revision, exc)
raise GitCloningError(repo, revision, exc)
if remove_git_dir:
rmdir(os.path.join(dirname, ".git"))
@@ -115,8 +105,7 @@ def checkout(cwd, repo, revision=None):
try:
return _checkout(cwd, repo, revision)
except CommandResultError as exc:
stderr = exc.stderr.decode("utf-8").strip()
bad_package_spec(repo, revision, stderr)
raise GitCheckoutError(repo=repo, revision=revision, error=exc)
def get_current_sha(cwd):
@@ -142,10 +131,10 @@ def clone_and_checkout(
subdirectory=subdirectory,
)
except CommandResultError as exc:
err = exc.stderr.decode("utf-8")
err = exc.stderr
exists = re.match("fatal: destination path '(.+)' already exists", err)
if not exists:
raise_git_cloning_problem(repo)
raise UnknownGitCloningProblemError(repo)
directory = None
start_sha = None
@@ -155,7 +144,7 @@ def clone_and_checkout(
else:
matches = re.match("Cloning into '(.+)'", err.decode("utf-8"))
if matches is None:
raise RuntimeException(f'Error cloning {repo} - never saw "Cloning into ..." from git')
raise DbtRuntimeError(f'Error cloning {repo} - never saw "Cloning into ..." from git')
directory = matches.group(1)
fire_event(GitProgressPullingNewDependency(dir=directory))
full_path = os.path.join(cwd, directory)

View File

@@ -25,18 +25,26 @@ from dbt.utils import (
)
from dbt.clients._jinja_blocks import BlockIterator, BlockData, BlockTag
from dbt.contracts.graph.compiled import CompiledGenericTestNode
from dbt.contracts.graph.parsed import ParsedGenericTestNode
from dbt.contracts.graph.nodes import GenericTestNode
from dbt.exceptions import (
InternalException,
raise_compiler_error,
CompilationException,
invalid_materialization_argument,
CaughtMacroError,
CaughtMacroErrorWithNodeError,
CompilationError,
DbtInternalError,
MaterializationArgError,
JinjaRenderingError,
MacroReturn,
JinjaRenderingException,
UndefinedMacroException,
MaterializtionMacroNotUsedError,
NoSupportedLanguagesFoundError,
UndefinedCompilationError,
UndefinedMacroError,
)
from dbt import flags
from dbt.flags import get_flags
from dbt.node_types import ModelLanguage
SUPPORTED_LANG_ARG = jinja2.nodes.Name("supported_languages", "param")
def _linecache_inject(source, write):
@@ -91,8 +99,9 @@ class MacroFuzzEnvironment(jinja2.sandbox.SandboxedEnvironment):
If the value is 'write', also write the files to disk.
WARNING: This can write a ton of data if you aren't careful.
"""
if filename == "<template>" and flags.MACRO_DEBUGGING:
write = flags.MACRO_DEBUGGING == "write"
macro_debugging = get_flags().MACRO_DEBUGGING
if filename == "<template>" and macro_debugging:
write = macro_debugging == "write"
filename = _linecache_inject(source, write)
return super()._compile(source, filename) # type: ignore
@@ -103,7 +112,7 @@ class NativeSandboxEnvironment(MacroFuzzEnvironment):
class TextMarker(str):
"""A special native-env marker that indicates that a value is text and is
"""A special native-env marker that indicates a value is text and is
not to be evaluated. Use this to prevent your numbery-strings from becoming
numbers!
"""
@@ -153,15 +162,15 @@ def quoted_native_concat(nodes):
except (ValueError, SyntaxError, MemoryError):
result = raw
if isinstance(raw, BoolMarker) and not isinstance(result, bool):
raise JinjaRenderingException(f"Could not convert value '{raw!s}' into type 'bool'")
raise JinjaRenderingError(f"Could not convert value '{raw!s}' into type 'bool'")
if isinstance(raw, NumberMarker) and not _is_number(result):
raise JinjaRenderingException(f"Could not convert value '{raw!s}' into type 'number'")
raise JinjaRenderingError(f"Could not convert value '{raw!s}' into type 'number'")
return result
class NativeSandboxTemplate(jinja2.nativetypes.NativeTemplate): # mypy: ignore
environment_class = NativeSandboxEnvironment
environment_class = NativeSandboxEnvironment # type: ignore
def render(self, *args, **kwargs):
"""Render the template to produce a native Python type. If the
@@ -233,12 +242,12 @@ class BaseMacroGenerator:
try:
yield
except (TypeError, jinja2.exceptions.TemplateRuntimeError) as e:
raise_compiler_error(str(e))
raise CaughtMacroError(e)
def call_macro(self, *args, **kwargs):
# called from __call__ methods
if self.context is None:
raise InternalException("Context is still None in call_macro!")
raise DbtInternalError("Context is still None in call_macro!")
assert self.context is not None
macro = self.get_macro()
@@ -265,7 +274,7 @@ class MacroStack(threading.local):
def pop(self, name):
got = self.call_stack.pop()
if got != name:
raise InternalException(f"popped {got}, expected {name}")
raise DbtInternalError(f"popped {got}, expected {name}")
class MacroGenerator(BaseMacroGenerator):
@@ -292,8 +301,8 @@ class MacroGenerator(BaseMacroGenerator):
try:
yield
except (TypeError, jinja2.exceptions.TemplateRuntimeError) as e:
raise_compiler_error(str(e), self.macro)
except CompilationException as e:
raise CaughtMacroErrorWithNodeError(exc=e, node=self.macro)
except CompilationError as e:
e.stack.append(self.macro)
raise e
@@ -301,13 +310,13 @@ class MacroGenerator(BaseMacroGenerator):
@contextmanager
def track_call(self):
# This is only called from __call__
if self.stack is None or self.node is None:
if self.stack is None:
yield
else:
unique_id = self.macro.unique_id
depth = self.stack.depth
# only mark depth=0 as a dependency
if depth == 0:
# only mark depth=0 as a dependency, when creating this dependency we don't pass in stack
if depth == 0 and self.node:
self.node.depends_on.add_macro(unique_id)
self.stack.push(unique_id)
try:
@@ -364,8 +373,19 @@ class MaterializationExtension(jinja2.ext.Extension):
value = parser.parse_expression()
adapter_name = value.value
elif target.name == "supported_languages":
target.set_ctx("param")
node.args.append(target)
parser.stream.expect("assign")
languages = parser.parse_expression()
node.defaults.append(languages)
else:
invalid_materialization_argument(materialization_name, target.name)
raise MaterializationArgError(materialization_name, target.name)
if SUPPORTED_LANG_ARG not in node.args:
node.args.append(SUPPORTED_LANG_ARG)
node.defaults.append(jinja2.nodes.List([jinja2.nodes.Const("sql")]))
node.name = get_materialization_macro_name(materialization_name, adapter_name)
@@ -436,7 +456,7 @@ def create_undefined(node=None):
return self
def __reduce__(self):
raise_compiler_error(f"{self.name} is undefined", node=node)
raise UndefinedCompilationError(name=self.name, node=node)
return Undefined
@@ -463,7 +483,7 @@ def get_environment(
native: bool = False,
) -> jinja2.Environment:
args: Dict[str, List[Union[str, Type[jinja2.ext.Extension]]]] = {
"extensions": ["jinja2.ext.do"]
"extensions": ["jinja2.ext.do", "jinja2.ext.loopcontrols"]
}
if capture_macros:
@@ -494,10 +514,10 @@ def catch_jinja(node=None) -> Iterator[None]:
yield
except jinja2.exceptions.TemplateSyntaxError as e:
e.translated = False
raise CompilationException(str(e), node) from e
raise CompilationError(str(e), node) from e
except jinja2.exceptions.UndefinedError as e:
raise UndefinedMacroException(str(e), node) from e
except CompilationException as exc:
raise UndefinedMacroError(str(e), node) from e
except CompilationError as exc:
exc.add_node(node)
raise
@@ -580,7 +600,7 @@ def extract_toplevel_blocks(
allowed_blocks: Optional[Set[str]] = None,
collect_raw_data: bool = True,
) -> List[Union[BlockData, BlockTag]]:
"""Extract the top level blocks with matching block types from a jinja
"""Extract the top-level blocks with matching block types from a jinja
file, with some special handling for block nesting.
:param data: The data to extract blocks from.
@@ -604,7 +624,7 @@ GENERIC_TEST_KWARGS_NAME = "_dbt_generic_test_kwargs"
def add_rendered_test_kwargs(
context: Dict[str, Any],
node: Union[ParsedGenericTestNode, CompiledGenericTestNode],
node: GenericTestNode,
capture_macros: bool = False,
) -> None:
"""Render each of the test kwargs in the given context using the native
@@ -632,3 +652,21 @@ def add_rendered_test_kwargs(
# when the test node was created in _parse_generic_test.
kwargs = deep_map_render(_convert_function, node.test_metadata.kwargs)
context[GENERIC_TEST_KWARGS_NAME] = kwargs
def get_supported_languages(node: jinja2.nodes.Macro) -> List[ModelLanguage]:
if "materialization" not in node.name:
raise MaterializtionMacroNotUsedError(node=node)
no_kwargs = not node.defaults
no_langs_found = SUPPORTED_LANG_ARG not in node.args
if no_kwargs or no_langs_found:
raise NoSupportedLanguagesFoundError(node=node)
lang_idx = node.args.index(SUPPORTED_LANG_ARG)
# indexing defaults from the end
# since supported_languages is a kwarg, and kwargs are at always after args
return [
ModelLanguage[item.value] for item in node.defaults[-(len(node.args) - lang_idx)].items
]

View File

@@ -1,6 +1,6 @@
import jinja2
from dbt.clients.jinja import get_environment
from dbt.exceptions import raise_compiler_error
from dbt.exceptions import MacroNamespaceNotStringError, MacroNameNotStringError
def statically_extract_macro_calls(string, ctx, db_wrapper=None):
@@ -15,7 +15,7 @@ def statically_extract_macro_calls(string, ctx, db_wrapper=None):
if hasattr(func_call, "node") and hasattr(func_call.node, "name"):
func_name = func_call.node.name
else:
# func_call for dbt_utils.current_timestamp macro
# func_call for dbt.current_timestamp macro
# Call(
# node=Getattr(
# node=Name(
@@ -117,20 +117,14 @@ def statically_parse_adapter_dispatch(func_call, ctx, db_wrapper):
func_name = kwarg.value.value
possible_macro_calls.append(func_name)
else:
raise_compiler_error(
f"The macro_name parameter ({kwarg.value.value}) "
"to adapter.dispatch was not a string"
)
raise MacroNameNotStringError(kwarg_value=kwarg.value.value)
elif kwarg.key == "macro_namespace":
# This will remain to enable static resolution
kwarg_type = type(kwarg.value).__name__
if kwarg_type == "Const":
macro_namespace = kwarg.value.value
else:
raise_compiler_error(
"The macro_namespace parameter to adapter.dispatch "
f"is a {kwarg_type}, not a string"
)
raise MacroNamespaceNotStringError(kwarg_type)
# positional arguments
if packages_arg:

View File

@@ -1,9 +1,20 @@
import functools
from typing import Any, Dict, List
import requests
from dbt.events.functions import fire_event
from dbt.events.types import RegistryProgressMakingGETRequest, RegistryProgressGETResponse
from dbt.events.types import (
RegistryProgressGETRequest,
RegistryProgressGETResponse,
RegistryIndexProgressGETRequest,
RegistryIndexProgressGETResponse,
RegistryResponseUnexpectedType,
RegistryResponseMissingTopKeys,
RegistryResponseMissingNestedKeys,
RegistryResponseExtraNestedKeys,
)
from dbt.utils import memoized, _connection_exception_retry as connection_exception_retry
from dbt import deprecations
from dbt import semver
import os
if os.getenv("DBT_PACKAGE_HUB_URL"):
@@ -12,55 +23,86 @@ else:
DEFAULT_REGISTRY_BASE_URL = "https://hub.getdbt.com/"
def _get_url(url, registry_base_url=None):
def _get_url(name, registry_base_url=None):
if registry_base_url is None:
registry_base_url = DEFAULT_REGISTRY_BASE_URL
url = "api/v1/{}.json".format(name)
return "{}{}".format(registry_base_url, url)
def _get_with_retries(path, registry_base_url=None):
get_fn = functools.partial(_get, path, registry_base_url)
def _get_with_retries(package_name, registry_base_url=None):
get_fn = functools.partial(_get, package_name, registry_base_url)
return connection_exception_retry(get_fn, 5)
def _get(path, registry_base_url=None):
url = _get_url(path, registry_base_url)
fire_event(RegistryProgressMakingGETRequest(url=url))
def _get(package_name, registry_base_url=None):
url = _get_url(package_name, registry_base_url)
fire_event(RegistryProgressGETRequest(url=url))
# all exceptions from requests get caught in the retry logic so no need to wrap this here
resp = requests.get(url, timeout=30)
fire_event(RegistryProgressGETResponse(url=url, resp_code=resp.status_code))
resp.raise_for_status()
# It is unexpected for the content of the response to be None so if it is, raising this error
# will cause this function to retry (if called within _get_with_retries) and hopefully get
# a response. This seems to happen when there's an issue with the Hub.
# The response should always be a dictionary. Anything else is unexpected, raise error.
# Raising this error will cause this function to retry (if called within _get_with_retries)
# and hopefully get a valid response. This seems to happen when there's an issue with the Hub.
# Since we control what we expect the HUB to return, this is safe.
# See https://github.com/dbt-labs/dbt-core/issues/4577
if resp.json() is None:
raise requests.exceptions.ContentDecodingError(
"Request error: The response is None", response=resp
# and https://github.com/dbt-labs/dbt-core/issues/4849
response = resp.json()
if not isinstance(response, dict): # This will also catch Nonetype
error_msg = (
f"Request error: Expected a response type of <dict> but got {type(response)} instead"
)
return resp.json()
fire_event(RegistryResponseUnexpectedType(response=response))
raise requests.exceptions.ContentDecodingError(error_msg, response=resp)
# check for expected top level keys
expected_keys = {"name", "versions"}
if not expected_keys.issubset(response):
error_msg = (
f"Request error: Expected the response to contain keys {expected_keys} "
f"but is missing {expected_keys.difference(set(response))}"
)
fire_event(RegistryResponseMissingTopKeys(response=response))
raise requests.exceptions.ContentDecodingError(error_msg, response=resp)
# check for the keys we need nested under each version
expected_version_keys = {"name", "packages", "downloads"}
all_keys = set().union(*(response["versions"][d] for d in response["versions"]))
if not expected_version_keys.issubset(all_keys):
error_msg = (
"Request error: Expected the response for the version to contain keys "
f"{expected_version_keys} but is missing {expected_version_keys.difference(all_keys)}"
)
fire_event(RegistryResponseMissingNestedKeys(response=response))
raise requests.exceptions.ContentDecodingError(error_msg, response=resp)
# all version responses should contain identical keys.
has_extra_keys = set().difference(*(response["versions"][d] for d in response["versions"]))
if has_extra_keys:
error_msg = (
"Request error: Keys for all versions do not match. Found extra key(s) "
f"of {has_extra_keys}."
)
fire_event(RegistryResponseExtraNestedKeys(response=response))
raise requests.exceptions.ContentDecodingError(error_msg, response=resp)
return response
def index(registry_base_url=None):
return _get_with_retries("api/v1/index.json", registry_base_url)
_get_cached = memoized(_get_with_retries)
index_cached = memoized(index)
def packages(registry_base_url=None):
return _get_with_retries("api/v1/packages.json", registry_base_url)
def package(name, registry_base_url=None):
response = _get_with_retries("api/v1/{}.json".format(name), registry_base_url)
def package(package_name, registry_base_url=None) -> Dict[str, Any]:
# returns a dictionary of metadata for all versions of a package
response = _get_cached(package_name, registry_base_url)
# Either redirectnamespace or redirectname in the JSON response indicate a redirect
# redirectnamespace redirects based on package ownership
# redirectname redirects based on package name
# Both can be present at the same time, or neither. Fails gracefully to old name
if ("redirectnamespace" in response) or ("redirectname" in response):
if ("redirectnamespace" in response) and response["redirectnamespace"] is not None:
@@ -74,15 +116,76 @@ def package(name, registry_base_url=None):
use_name = response["name"]
new_nwo = use_namespace + "/" + use_name
deprecations.warn("package-redirect", old_name=name, new_name=new_nwo)
deprecations.warn("package-redirect", old_name=package_name, new_name=new_nwo)
return response["versions"]
def package_version(package_name, version, registry_base_url=None) -> Dict[str, Any]:
# returns the metadata of a specific version of a package
response = package(package_name, registry_base_url)
return response[version]
def is_compatible_version(package_spec, dbt_version) -> bool:
require_dbt_version = package_spec.get("require_dbt_version")
if not require_dbt_version:
# if version requirements are missing or empty, assume any version is compatible
return True
else:
# determine whether dbt_version satisfies this package's require-dbt-version config
if not isinstance(require_dbt_version, list):
require_dbt_version = [require_dbt_version]
supported_versions = [
semver.VersionSpecifier.from_version_string(v) for v in require_dbt_version
]
return semver.versions_compatible(dbt_version, *supported_versions)
def get_compatible_versions(package_name, dbt_version, should_version_check) -> List["str"]:
# returns a list of all available versions of a package
response = package(package_name)
# if the user doesn't care about installing compatible versions, just return them all
if not should_version_check:
return list(response)
# otherwise, only return versions that are compatible with the installed version of dbt-core
else:
compatible_versions = [
pkg_version
for pkg_version, info in response.items()
if is_compatible_version(info, dbt_version)
]
return compatible_versions
def _get_index(registry_base_url=None):
url = _get_url("index", registry_base_url)
fire_event(RegistryIndexProgressGETRequest(url=url))
# all exceptions from requests get caught in the retry logic so no need to wrap this here
resp = requests.get(url, timeout=30)
fire_event(RegistryIndexProgressGETResponse(url=url, resp_code=resp.status_code))
resp.raise_for_status()
# The response should be a list. Anything else is unexpected, raise an error.
# Raising this error will cause this function to retry and hopefully get a valid response.
response = resp.json()
if not isinstance(response, list): # This will also catch Nonetype
error_msg = (
f"Request error: The response type of {type(response)} is not valid: {resp.text}"
)
raise requests.exceptions.ContentDecodingError(error_msg, response=resp)
return response
def package_version(name, version, registry_base_url=None):
return _get_with_retries("api/v1/{}/{}.json".format(name, version), registry_base_url)
def index(registry_base_url=None) -> List[str]:
# this returns a list of all packages on the Hub
get_index_fn = functools.partial(_get_index, registry_base_url)
return connection_exception_retry(get_index_fn, 5)
def get_available_versions(name):
response = package(name)
return list(response["versions"])
index_cached = memoized(index)

View File

@@ -1,29 +1,31 @@
import errno
import functools
import fnmatch
import functools
import json
import os
import os.path
import re
import shutil
import stat
import subprocess
import sys
import tarfile
import requests
import stat
from typing import Type, NoReturn, List, Optional, Dict, Any, Tuple, Callable, Union
from pathlib import Path
from typing import Any, Callable, Dict, List, NoReturn, Optional, Tuple, Type, Union
import dbt.exceptions
import requests
from dbt.events.functions import fire_event
from dbt.events.types import (
SystemErrorRetrievingModTime,
SystemCouldNotWrite,
SystemExecutingCmd,
SystemStdOutMsg,
SystemStdErrMsg,
SystemStdOut,
SystemStdErr,
SystemReportReturnCode,
)
import dbt.exceptions
from dbt.exceptions import DbtInternalError
from dbt.utils import _connection_exception_retry as connection_exception_retry
from pathspec import PathSpec # type: ignore
if sys.platform == "win32":
from ctypes import WinDLL, c_bool
@@ -36,6 +38,7 @@ def find_matching(
root_path: str,
relative_paths_to_search: List[str],
file_pattern: str,
ignore_spec: Optional[PathSpec] = None,
) -> List[Dict[str, Any]]:
"""
Given an absolute `root_path`, a list of relative paths to that
@@ -57,19 +60,26 @@ def find_matching(
reobj = re.compile(regex, re.IGNORECASE)
for relative_path_to_search in relative_paths_to_search:
# potential speedup for ignore_spec
# if ignore_spec.matches(relative_path_to_search):
# continue
absolute_path_to_search = os.path.join(root_path, relative_path_to_search)
walk_results = os.walk(absolute_path_to_search)
for current_path, subdirectories, local_files in walk_results:
# potential speedup for ignore_spec
# relative_dir = os.path.relpath(current_path, root_path) + os.sep
# if ignore_spec.match(relative_dir):
# continue
for local_file in local_files:
absolute_path = os.path.join(current_path, local_file)
relative_path = os.path.relpath(absolute_path, absolute_path_to_search)
modification_time = 0.0
try:
modification_time = os.path.getmtime(absolute_path)
except OSError:
fire_event(SystemErrorRetrievingModTime(path=absolute_path))
if reobj.match(local_file):
relative_path_to_root = os.path.join(relative_path_to_search, relative_path)
modification_time = os.path.getmtime(absolute_path)
if reobj.match(local_file) and (
not ignore_spec or not ignore_spec.match_file(relative_path_to_root)
):
matching.append(
{
"searched_path": relative_path_to_search,
@@ -93,12 +103,18 @@ def load_file_contents(path: str, strip: bool = True) -> str:
return to_return
def make_directory(path: str) -> None:
@functools.singledispatch
def make_directory(path=None) -> None:
"""
Make a directory and any intermediate directories that don't already
exist. This function handles the case where two threads try to create
a directory at once.
"""
raise DbtInternalError(f"Can not create directory from {type(path)} ")
@make_directory.register
def _(path: str) -> None:
path = convert_path(path)
if not os.path.exists(path):
# concurrent writes that try to create the same dir can fail
@@ -112,6 +128,11 @@ def make_directory(path: str) -> None:
raise e
@make_directory.register
def _(path: Path) -> None:
path.mkdir(parents=True, exist_ok=True)
def make_file(path: str, contents: str = "", overwrite: bool = False) -> bool:
"""
Make a file at `path` assuming that the directory it resides in already
@@ -131,7 +152,8 @@ def make_symlink(source: str, link_path: str) -> None:
Create a symlink at `link_path` referring to `source`.
"""
if not supports_symlinks():
dbt.exceptions.system_error("create a symbolic link")
# TODO: why not import these at top?
raise dbt.exceptions.SymbolicLinkError()
os.symlink(source, link_path)
@@ -164,7 +186,7 @@ def write_file(path: str, contents: str = "") -> bool:
reason = "Path was possibly too long"
# all our hard work and the path was still too long. Log and
# continue.
fire_event(SystemCouldNotWrite(path=path, reason=reason, exc=exc))
fire_event(SystemCouldNotWrite(path=path, reason=reason, exc=str(exc)))
else:
raise
return True
@@ -189,7 +211,7 @@ def _windows_rmdir_readonly(func: Callable[[str], Any], path: str, exc: Tuple[An
def resolve_path_from_base(path_to_resolve: str, base_path: str) -> str:
"""
If path-to_resolve is a relative path, create an absolute path
If path_to_resolve is a relative path, create an absolute path
with base_path as the base.
If path_to_resolve is an absolute path or a user path (~), just
@@ -246,16 +268,17 @@ def _supports_long_paths() -> bool:
# https://stackoverflow.com/a/35097999/11262881
# I don't know exaclty what he means, but I am inclined to believe him as
# he's pretty active on Python windows bugs!
try:
dll = WinDLL("ntdll")
except OSError: # I don't think this happens? you need ntdll to run python
return False
# not all windows versions have it at all
if not hasattr(dll, "RtlAreLongPathsEnabled"):
return False
# tell windows we want to get back a single unsigned byte (a bool).
dll.RtlAreLongPathsEnabled.restype = c_bool
return dll.RtlAreLongPathsEnabled()
else:
try:
dll = WinDLL("ntdll")
except OSError: # I don't think this happens? you need ntdll to run python
return False
# not all windows versions have it at all
if not hasattr(dll, "RtlAreLongPathsEnabled"):
return False
# tell windows we want to get back a single unsigned byte (a bool).
dll.RtlAreLongPathsEnabled.restype = c_bool
return dll.RtlAreLongPathsEnabled()
def convert_path(path: str) -> str:
@@ -335,7 +358,7 @@ def _handle_posix_cmd_error(exc: OSError, cwd: str, cmd: List[str]) -> NoReturn:
def _handle_posix_error(exc: OSError, cwd: str, cmd: List[str]) -> NoReturn:
"""OSError handling for posix systems.
"""OSError handling for POSIX systems.
Some things that could happen to trigger an OSError:
- cwd could not exist
@@ -386,7 +409,7 @@ def _handle_windows_error(exc: OSError, cwd: str, cmd: List[str]) -> NoReturn:
def _interpret_oserror(exc: OSError, cwd: str, cmd: List[str]) -> NoReturn:
"""Interpret an OSError exc and raise the appropriate dbt exception."""
"""Interpret an OSError exception and raise the appropriate dbt exception."""
if len(cmd) == 0:
raise dbt.exceptions.CommandError(cwd, cmd)
@@ -397,7 +420,7 @@ def _interpret_oserror(exc: OSError, cwd: str, cmd: List[str]) -> NoReturn:
_handle_posix_error(exc, cwd, cmd)
# this should not be reachable, raise _something_ at least!
raise dbt.exceptions.InternalException(
raise dbt.exceptions.DbtInternalError(
"Unhandled exception in _interpret_oserror: {}".format(exc)
)
@@ -426,8 +449,8 @@ def run_cmd(cwd: str, cmd: List[str], env: Optional[Dict[str, Any]] = None) -> T
except OSError as exc:
_interpret_oserror(exc, cwd, cmd)
fire_event(SystemStdOutMsg(bmsg=out))
fire_event(SystemStdErrMsg(bmsg=err))
fire_event(SystemStdOut(bmsg=str(out)))
fire_event(SystemStdErr(bmsg=str(err)))
if proc.returncode != 0:
fire_event(SystemReportReturnCode(returncode=proc.returncode))
@@ -443,7 +466,11 @@ def download_with_retries(
connection_exception_retry(download_fn, 5)
def download(url: str, path: str, timeout: Optional[Union[float, tuple]] = None) -> None:
def download(
url: str,
path: str,
timeout: Optional[Union[float, Tuple[float, float], Tuple[float, None]]] = None,
) -> None:
path = convert_path(path)
connection_timeout = timeout or float(os.getenv("DBT_HTTP_TIMEOUT", 10))
response = requests.get(url, timeout=connection_timeout)
@@ -501,7 +528,7 @@ def move(src, dst):
directory on windows when it has read-only files in it and the move is
between two drives.
This is almost identical to the real shutil.move, except it uses our rmtree
This is almost identical to the real shutil.move, except it, uses our rmtree
and skips handling non-windows OSes since the existing one works ok there.
"""
src = convert_path(src)
@@ -536,7 +563,7 @@ def move(src, dst):
def rmtree(path):
"""Recursively remove path. On permissions errors on windows, try to remove
"""Recursively remove the path. On permissions errors on windows, try to remove
the read-only flag and try again.
"""
path = convert_path(path)

View File

@@ -51,7 +51,7 @@ def safe_load(contents) -> Optional[Dict[str, Any]]:
return yaml.load(contents, Loader=SafeLoader)
def load_yaml_text(contents):
def load_yaml_text(contents, path=None):
try:
return safe_load(contents)
except (yaml.scanner.ScannerError, yaml.YAMLError) as e:
@@ -60,4 +60,4 @@ def load_yaml_text(contents):
else:
error = str(e)
raise dbt.exceptions.ValidationException(error)
raise dbt.exceptions.DbtValidationError(error)

View File

@@ -1,49 +1,43 @@
import os
from collections import defaultdict
from typing import List, Dict, Any, Tuple, cast, Optional
import argparse
import networkx as nx # type: ignore
import os
import pickle
import sqlparse
from dbt import flags
from collections import defaultdict
from typing import List, Dict, Any, Tuple, Optional
from dbt.flags import get_flags
from dbt.adapters.factory import get_adapter
from dbt.clients import jinja
from dbt.clients.system import make_directory
from dbt.context.providers import generate_runtime_model_context
from dbt.contracts.graph.manifest import Manifest, UniqueID
from dbt.contracts.graph.compiled import (
COMPILED_TYPES,
CompiledGenericTestNode,
from dbt.contracts.graph.nodes import (
ManifestNode,
ManifestSQLNode,
GenericTestNode,
GraphMemberNode,
InjectedCTE,
ManifestNode,
NonSourceCompiledNode,
SeedNode,
)
from dbt.contracts.graph.parsed import ParsedNode
from dbt.exceptions import (
dependency_not_found,
InternalException,
RuntimeException,
GraphDependencyNotFoundError,
DbtInternalError,
DbtRuntimeError,
)
from dbt.graph import Graph
from dbt.events.functions import fire_event
from dbt.events.types import FoundStats, CompilingNode, WritingInjectedSQLForNode
from dbt.node_types import NodeType
from dbt.events.types import FoundStats, WritingInjectedSQLForNode
from dbt.events.contextvars import get_node_info
from dbt.node_types import NodeType, ModelLanguage
from dbt.events.format import pluralize
import dbt.tracking
import dbt.task.list as list_task
graph_file_name = "graph.gpickle"
def _compiled_type_for(model: ParsedNode):
if type(model) not in COMPILED_TYPES:
raise InternalException(
f"Asked to compile {type(model)} node, but it has no compiled form"
)
return COMPILED_TYPES[type(model)]
def print_compile_stats(stats):
names = {
NodeType.Model: "model",
@@ -56,6 +50,7 @@ def print_compile_stats(stats):
NodeType.Source: "source",
NodeType.Exposure: "exposure",
NodeType.Metric: "metric",
NodeType.Group: "group",
}
results = {k: 0 for k in names.keys()}
@@ -93,15 +88,18 @@ def _generate_stats(manifest: Manifest):
stats[metric.resource_type] += 1
for macro in manifest.macros.values():
stats[macro.resource_type] += 1
for group in manifest.groups.values():
stats[group.resource_type] += 1
return stats
def _add_prepended_cte(prepended_ctes, new_cte):
for cte in prepended_ctes:
if cte.id == new_cte.id:
if cte.id == new_cte.id and new_cte.sql:
cte.sql = new_cte.sql
return
prepended_ctes.append(new_cte)
if new_cte.sql:
prepended_ctes.append(new_cte)
def _extend_prepended_ctes(prepended_ctes, new_prepended_ctes):
@@ -169,21 +167,22 @@ class Compiler:
self.config = config
def initialize(self):
make_directory(self.config.target_path)
make_directory(self.config.project_target_path)
make_directory(self.config.packages_install_path)
# creates a ModelContext which is converted to
# a dict for jinja rendering of SQL
def _create_node_context(
self,
node: NonSourceCompiledNode,
node: ManifestSQLNode,
manifest: Manifest,
extra_context: Dict[str, Any],
) -> Dict[str, Any]:
context = generate_runtime_model_context(node, self.config, manifest)
context.update(extra_context)
if isinstance(node, CompiledGenericTestNode):
if isinstance(node, GenericTestNode):
# for test nodes, add a special keyword args value to the context
jinja.add_rendered_test_kwargs(context, node)
@@ -194,14 +193,6 @@ class Compiler:
relation_cls = adapter.Relation
return relation_cls.add_ephemeral_prefix(name)
def _get_relation_name(self, node: ParsedNode):
relation_name = None
if node.is_relational and not node.is_ephemeral_model:
adapter = get_adapter(self.config)
relation_cls = adapter.Relation
relation_name = str(relation_cls.create_from(self.config, node))
return relation_name
def _inject_ctes_into_sql(self, sql: str, ctes: List[InjectedCTE]) -> str:
"""
`ctes` is a list of InjectedCTEs like:
@@ -260,10 +251,10 @@ class Compiler:
def _recursively_prepend_ctes(
self,
model: NonSourceCompiledNode,
model: ManifestSQLNode,
manifest: Manifest,
extra_context: Optional[Dict[str, Any]],
) -> Tuple[NonSourceCompiledNode, List[InjectedCTE]]:
) -> Tuple[ManifestSQLNode, List[InjectedCTE]]:
"""This method is called by the 'compile_node' method. Starting
from the node that it is passed in, it will recursively call
itself using the 'extra_ctes'. The 'ephemeral' models do
@@ -271,16 +262,19 @@ class Compiler:
are rolled up into the models that refer to them by
inserting CTEs into the SQL.
"""
if model.compiled_sql is None:
raise RuntimeException("Cannot inject ctes into an unparsed node", model)
if model.compiled_code is None:
raise DbtRuntimeError("Cannot inject ctes into an uncompiled node", model)
# extra_ctes_injected flag says that we've already recursively injected the ctes
if model.extra_ctes_injected:
return (model, model.extra_ctes)
# Just to make it plain that nothing is actually injected for this case
if not model.extra_ctes:
model.extra_ctes_injected = True
manifest.update_node(model)
return (model, model.extra_ctes)
if len(model.extra_ctes) == 0:
# SeedNodes don't have compilation attributes
if not isinstance(model, SeedNode):
model.extra_ctes_injected = True
return (model, [])
# This stores the ctes which will all be recursively
# gathered and then "injected" into the model.
@@ -289,103 +283,112 @@ class Compiler:
# extra_ctes are added to the model by
# RuntimeRefResolver.create_relation, which adds an
# extra_cte for every model relation which is an
# ephemeral model.
# ephemeral model. InjectedCTEs have a unique_id and sql.
# extra_ctes start out with sql set to None, and the sql is set in this loop.
for cte in model.extra_ctes:
if cte.id not in manifest.nodes:
raise InternalException(
raise DbtInternalError(
f"During compilation, found a cte reference that "
f"could not be resolved: {cte.id}"
)
cte_model = manifest.nodes[cte.id]
assert not isinstance(cte_model, SeedNode)
if not cte_model.is_ephemeral_model:
raise InternalException(f"{cte.id} is not ephemeral")
raise DbtInternalError(f"{cte.id} is not ephemeral")
# This model has already been compiled, so it's been
# through here before
if getattr(cte_model, "compiled", False):
assert isinstance(cte_model, tuple(COMPILED_TYPES.values()))
cte_model = cast(NonSourceCompiledNode, cte_model)
# This model has already been compiled and extra_ctes_injected, so it's been
# through here before. We already checked above for extra_ctes_injected, but
# checking again because updates maybe have happened in another thread.
if cte_model.compiled is True and cte_model.extra_ctes_injected is True:
new_prepended_ctes = cte_model.extra_ctes
# if the cte_model isn't compiled, i.e. first time here
else:
# This is an ephemeral parsed model that we can compile.
# Compile and update the node
cte_model = self._compile_node(cte_model, manifest, extra_context)
# recursively call this method
# Render the raw_code and set compiled to True
cte_model = self._compile_code(cte_model, manifest, extra_context)
# recursively call this method, sets extra_ctes_injected to True
cte_model, new_prepended_ctes = self._recursively_prepend_ctes(
cte_model, manifest, extra_context
)
# Save compiled SQL file and sync manifest
# Write compiled SQL file
self._write_node(cte_model)
manifest.sync_update_node(cte_model)
_extend_prepended_ctes(prepended_ctes, new_prepended_ctes)
new_cte_name = self.add_ephemeral_prefix(cte_model.name)
rendered_sql = cte_model._pre_injected_sql or cte_model.compiled_sql
rendered_sql = cte_model._pre_injected_sql or cte_model.compiled_code
sql = f" {new_cte_name} as (\n{rendered_sql}\n)"
_add_prepended_cte(prepended_ctes, InjectedCTE(id=cte.id, sql=sql))
injected_sql = self._inject_ctes_into_sql(
model.compiled_sql,
prepended_ctes,
)
model._pre_injected_sql = model.compiled_sql
model.compiled_sql = injected_sql
model.extra_ctes_injected = True
model.extra_ctes = prepended_ctes
model.validate(model.to_dict(omit_none=True))
# Check again before updating for multi-threading
if not model.extra_ctes_injected:
injected_sql = self._inject_ctes_into_sql(
model.compiled_code,
prepended_ctes,
)
model.extra_ctes_injected = True
model._pre_injected_sql = model.compiled_code
model.compiled_code = injected_sql
model.extra_ctes = prepended_ctes
manifest.update_node(model)
# if model.extra_ctes is not set to prepended ctes, something went wrong
return model, model.extra_ctes
return model, prepended_ctes
# creates a compiled_node from the ManifestNode passed in,
# Sets compiled_code and compiled flag in the ManifestSQLNode passed in,
# creates a "context" dictionary for jinja rendering,
# and then renders the "compiled_sql" using the node, the
# raw_sql and the context.
def _compile_node(
# and then renders the "compiled_code" using the node, the
# raw_code and the context.
def _compile_code(
self,
node: ManifestNode,
node: ManifestSQLNode,
manifest: Manifest,
extra_context: Optional[Dict[str, Any]] = None,
) -> NonSourceCompiledNode:
) -> ManifestSQLNode:
if extra_context is None:
extra_context = {}
fire_event(CompilingNode(unique_id=node.unique_id))
if node.language == ModelLanguage.python:
context = self._create_node_context(node, manifest, extra_context)
data = node.to_dict(omit_none=True)
data.update(
{
"compiled": False,
"compiled_sql": None,
"extra_ctes_injected": False,
"extra_ctes": [],
}
)
compiled_node = _compiled_type_for(node).from_dict(data)
postfix = jinja.get_rendered(
"{{ py_script_postfix(model) }}",
context,
node,
)
# we should NOT jinja render the python model's 'raw code'
node.compiled_code = f"{node.raw_code}\n\n{postfix}"
context = self._create_node_context(compiled_node, manifest, extra_context)
else:
context = self._create_node_context(node, manifest, extra_context)
node.compiled_code = jinja.get_rendered(
node.raw_code,
context,
node,
)
compiled_node.compiled_sql = jinja.get_rendered(
node.raw_sql,
context,
node,
)
node.compiled = True
compiled_node.relation_name = self._get_relation_name(node)
# relation_name is set at parse time, except for tests without store_failures,
# but cli param can turn on store_failures, so we set here.
if (
node.resource_type == NodeType.Test
and node.relation_name is None
and node.is_relational
):
adapter = get_adapter(self.config)
relation_cls = adapter.Relation
relation_name = str(relation_cls.create_from(self.config, node))
node.relation_name = relation_name
compiled_node.compiled = True
return compiled_node
return node
def write_graph_file(self, linker: Linker, manifest: Manifest):
filename = graph_file_name
graph_path = os.path.join(self.config.target_path, filename)
graph_path = os.path.join(self.config.project_target_path, filename)
flags = get_flags()
if flags.WRITE_JSON:
linker.write_graph(graph_path, manifest)
@@ -397,8 +400,10 @@ class Compiler:
linker.dependency(node.unique_id, (manifest.nodes[dependency].unique_id))
elif dependency in manifest.sources:
linker.dependency(node.unique_id, (manifest.sources[dependency].unique_id))
elif dependency in manifest.metrics:
linker.dependency(node.unique_id, (manifest.metrics[dependency].unique_id))
else:
dependency_not_found(node, dependency)
raise GraphDependencyNotFoundError(node, dependency)
def link_graph(self, linker: Linker, manifest: Manifest, add_test_edges: bool = False):
for source in manifest.sources.values():
@@ -481,36 +486,50 @@ class Compiler:
if write:
self.write_graph_file(linker, manifest)
print_compile_stats(stats)
# Do not print these for ListTask's
if not (
self.config.args.__class__ == argparse.Namespace
and self.config.args.cls == list_task.ListTask
):
print_compile_stats(stats)
return Graph(linker.graph)
# writes the "compiled_sql" into the target/compiled directory
def _write_node(self, node: NonSourceCompiledNode) -> ManifestNode:
if not node.extra_ctes_injected or node.resource_type == NodeType.Snapshot:
# writes the "compiled_code" into the target/compiled directory
def _write_node(self, node: ManifestSQLNode) -> ManifestSQLNode:
if not node.extra_ctes_injected or node.resource_type in (
NodeType.Snapshot,
NodeType.Seed,
):
return node
fire_event(WritingInjectedSQLForNode(unique_id=node.unique_id))
fire_event(WritingInjectedSQLForNode(node_info=get_node_info()))
if node.compiled_sql:
node.compiled_path = node.write_node(
self.config.target_path, "compiled", node.compiled_sql
)
if node.compiled_code:
node.compiled_path = node.get_target_write_path(self.config.target_path, "compiled")
node.write_node(self.config.project_root, node.compiled_path, node.compiled_code)
return node
def compile_node(
self,
node: ManifestNode,
node: ManifestSQLNode,
manifest: Manifest,
extra_context: Optional[Dict[str, Any]] = None,
write: bool = True,
) -> NonSourceCompiledNode:
) -> ManifestSQLNode:
"""This is the main entry point into this code. It's called by
CompileRunner.compile, GenericRPCRunner.compile, and
RunTask.get_hook_sql. It calls '_compile_node' to convert
the node into a compiled node, and then calls the
RunTask.get_hook_sql. It calls '_compile_code' to render
the node's raw_code into compiled_code, and then calls the
recursive method to "prepend" the ctes.
"""
node = self._compile_node(node, manifest, extra_context)
# Make sure Lexer for sqlparse 0.4.4 is initialized
from sqlparse.lexer import Lexer # type: ignore
if hasattr(Lexer, "get_default_instance"):
Lexer.get_default_instance()
node = self._compile_code(node, manifest, extra_context)
node, _ = self._recursively_prepend_ctes(node, manifest, extra_context)
if write:

View File

@@ -1,4 +1,4 @@
# all these are just exports, they need "noqa" so flake8 will not complain.
from .profile import Profile, read_user_config # noqa
from .project import Project, IsFQNResource # noqa
from .runtime import RuntimeConfig, UnsetProfileConfig # noqa
from .project import Project, IsFQNResource, PartialProject # noqa
from .runtime import RuntimeConfig # noqa

View File

@@ -4,17 +4,19 @@ import os
from dbt.dataclass_schema import ValidationError
from dbt import flags
from dbt.flags import get_flags
from dbt.clients.system import load_file_contents
from dbt.clients.yaml_helper import load_yaml_text
from dbt.contracts.connection import Credentials, HasCredentials
from dbt.contracts.project import ProfileConfig, UserConfig
from dbt.exceptions import CompilationException
from dbt.exceptions import DbtProfileError
from dbt.exceptions import DbtProjectError
from dbt.exceptions import ValidationException
from dbt.exceptions import RuntimeException
from dbt.exceptions import validator_error_message
from dbt.exceptions import (
CompilationError,
DbtProfileError,
DbtProjectError,
DbtValidationError,
DbtRuntimeError,
ProfileConfigError,
)
from dbt.events.types import MissingProfileTarget
from dbt.events.functions import fire_event
from dbt.utils import coerce_dict_str
@@ -23,8 +25,6 @@ from .renderer import ProfileRenderer
DEFAULT_THREADS = 1
DEFAULT_PROFILES_DIR = os.path.join(os.path.expanduser("~"), ".dbt")
INVALID_PROFILE_MESSAGE = """
dbt encountered an error while trying to read your profiles.yml file.
@@ -32,22 +32,6 @@ dbt encountered an error while trying to read your profiles.yml file.
"""
NO_SUPPLIED_PROFILE_ERROR = """\
dbt cannot run because no profile was specified for this dbt project.
To specify a profile for this project, add a line like the this to
your dbt_project.yml file:
profile: [profile name]
Here, [profile name] should be replaced with a profile name
defined in your profiles.yml file. You can find profiles.yml here:
{profiles_file}/profiles.yml
""".format(
profiles_file=DEFAULT_PROFILES_DIR
)
def read_profile(profiles_dir: str) -> Dict[str, Any]:
path = os.path.join(profiles_dir, "profiles.yml")
@@ -60,9 +44,9 @@ def read_profile(profiles_dir: str) -> Dict[str, Any]:
msg = f"The profiles.yml file at {path} is empty"
raise DbtProfileError(INVALID_PROFILE_MESSAGE.format(error_string=msg))
return yaml_content
except ValidationException as e:
except DbtValidationError as e:
msg = INVALID_PROFILE_MESSAGE.format(error_string=e)
raise ValidationException(msg) from e
raise DbtValidationError(msg) from e
return {}
@@ -75,7 +59,7 @@ def read_user_config(directory: str) -> UserConfig:
if user_config is not None:
UserConfig.validate(user_config)
return UserConfig.from_dict(user_config)
except (RuntimeException, ValidationError):
except (DbtRuntimeError, ValidationError):
pass
return UserConfig()
@@ -158,7 +142,7 @@ class Profile(HasCredentials):
dct = self.to_profile_info(serialize_credentials=True)
ProfileConfig.validate(dct)
except ValidationError as exc:
raise DbtProfileError(validator_error_message(exc)) from exc
raise ProfileConfigError(exc) from exc
@staticmethod
def _credentials_from_profile(
@@ -182,8 +166,8 @@ class Profile(HasCredentials):
data = cls.translate_aliases(profile)
cls.validate(data)
credentials = cls.from_dict(data)
except (RuntimeException, ValidationError) as e:
msg = str(e) if isinstance(e, RuntimeException) else e.message
except (DbtRuntimeError, ValidationError) as e:
msg = str(e) if isinstance(e, DbtRuntimeError) else e.message
raise DbtProfileError(
'Credentials in profile "{}", target "{}" invalid: {}'.format(
profile_name, target_name, msg
@@ -197,10 +181,33 @@ class Profile(HasCredentials):
args_profile_name: Optional[str],
project_profile_name: Optional[str] = None,
) -> str:
# TODO: Duplicating this method as direct copy of the implementation in dbt.cli.resolvers
# dbt.cli.resolvers implementation can't be used because it causes a circular dependency.
# This should be removed and use a safe default access on the Flags module when
# https://github.com/dbt-labs/dbt-core/issues/6259 is closed.
def default_profiles_dir():
from pathlib import Path
return Path.cwd() if (Path.cwd() / "profiles.yml").exists() else Path.home() / ".dbt"
profile_name = project_profile_name
if args_profile_name is not None:
profile_name = args_profile_name
if profile_name is None:
NO_SUPPLIED_PROFILE_ERROR = """\
dbt cannot run because no profile was specified for this dbt project.
To specify a profile for this project, add a line like the this to
your dbt_project.yml file:
profile: [profile name]
Here, [profile name] should be replaced with a profile name
defined in your profiles.yml file. You can find profiles.yml here:
{profiles_file}/profiles.yml
""".format(
profiles_file=default_profiles_dir()
)
raise DbtProjectError(NO_SUPPLIED_PROFILE_ERROR)
return profile_name
@@ -299,7 +306,7 @@ class Profile(HasCredentials):
try:
profile_data = renderer.render_data(raw_profile_data)
except CompilationException as exc:
except CompilationError as exc:
raise DbtProfileError(str(exc)) from exc
return target_name, profile_data
@@ -401,11 +408,13 @@ class Profile(HasCredentials):
)
@classmethod
def render_from_args(
def render(
cls,
args: Any,
renderer: ProfileRenderer,
project_profile_name: Optional[str],
profile_name_override: Optional[str] = None,
target_override: Optional[str] = None,
threads_override: Optional[int] = None,
) -> "Profile":
"""Given the raw profiles as read from disk and the name of the desired
profile if specified, return the profile component of the runtime
@@ -421,10 +430,9 @@ class Profile(HasCredentials):
target could not be found.
:returns Profile: The new Profile object.
"""
threads_override = getattr(args, "threads", None)
target_override = getattr(args, "target", None)
flags = get_flags()
raw_profiles = read_profile(flags.PROFILES_DIR)
profile_name = cls.pick_profile_name(getattr(args, "profile", None), project_profile_name)
profile_name = cls.pick_profile_name(profile_name_override, project_profile_name)
return cls.from_raw_profiles(
raw_profiles=raw_profiles,
profile_name=profile_name,

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