dbt-adapters 1.0.0b1__tar.gz → 1.0.8b3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dbt-adapters might be problematic. Click here for more details.
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/PKG-INFO +2 -2
- dbt_adapters-1.0.8b3/dbt/adapters/__about__.py +1 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/connections.py +6 -5
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/impl.py +156 -67
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/relation.py +2 -2
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/capability.py +3 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/contracts/relation.py +4 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/events/adapter_types.proto +10 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/events/adapter_types_pb2.py +5 -2
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/events/types.py +15 -1
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/factory.py +18 -4
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/protocol.py +5 -2
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/relation_configs/config_base.py +5 -3
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/sql/connections.py +10 -5
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/sql/impl.py +13 -9
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/tests/unit.sql +6 -2
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/materialized_view/drop.sql +1 -1
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/table/drop.sql +1 -1
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/view/drop.sql +1 -1
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/pyproject.toml +2 -1
- dbt_adapters-1.0.0b1/dbt/adapters/__about__.py +0 -1
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/.gitignore +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/LICENSE +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/README.md +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/README.md +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/column.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/meta.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/plugin.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/base/query_headers.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/cache.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/clients/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/clients/jinja.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/contracts/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/contracts/connection.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/contracts/macros.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/events/README.md +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/events/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/events/base_types.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/events/logging.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/exceptions/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/exceptions/alias.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/exceptions/cache.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/exceptions/compilation.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/exceptions/connection.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/exceptions/database.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/py.typed +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/reference_keys.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/relation_configs/README.md +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/relation_configs/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/relation_configs/config_change.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/relation_configs/config_validation.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/sql/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/adapters/utils.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/__init__.py +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/dbt_project.yml +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/docs/overview.md +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/apply_grants.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/columns.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/freshness.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/indexes.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/metadata.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/persist_docs.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/relation.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/schema.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/show.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/timestamps.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/adapters/validate_sql.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/etc/datetime.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/etc/statement.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/generic_test_sql/accepted_values.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/generic_test_sql/not_null.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/generic_test_sql/relationships.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/generic_test_sql/unique.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/get_custom_name/get_custom_alias.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/get_custom_name/get_custom_database.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/get_custom_name/get_custom_schema.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/configs.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/hooks.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/clone/can_clone_table.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/clone/clone.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/clone/create_or_replace_clone.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/incremental/column_helpers.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/incremental/incremental.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/incremental/is_incremental.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/incremental/merge.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/incremental/on_schema_change.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/incremental/strategies.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/materialized_view.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/table.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/models/view.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/seeds/helpers.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/seeds/seed.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/snapshots/helpers.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/snapshots/snapshot.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/snapshots/snapshot_merge.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/snapshots/strategies.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/tests/helpers.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/tests/test.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/materializations/tests/where_subquery.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/python_model/python.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/column/columns_spec_ddl.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/create.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/create_backup.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/create_intermediate.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/drop.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/drop_backup.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/materialized_view/alter.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/materialized_view/create.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/materialized_view/refresh.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/materialized_view/rename.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/materialized_view/replace.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/rename.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/rename_intermediate.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/replace.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/schema.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/table/create.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/table/rename.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/table/replace.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/view/create.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/view/rename.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/relations/view/replace.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/unit_test_sql/get_fixture_sql.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/any_value.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/array_append.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/array_concat.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/array_construct.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/bool_or.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/cast.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/cast_bool_to_text.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/concat.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/data_types.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/date_spine.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/date_trunc.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/dateadd.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/datediff.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/escape_single_quotes.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/except.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/generate_series.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/hash.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/intersect.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/last_day.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/length.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/listagg.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/literal.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/position.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/replace.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/right.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/safe_cast.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/macros/utils/split_part.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/global_project/tests/generic/builtin.sql +0 -0
- {dbt_adapters-1.0.0b1 → dbt_adapters-1.0.8b3}/dbt/include/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: dbt-adapters
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.8b3
|
|
4
4
|
Summary: The set of adapter protocols and base functionality that supports integration with dbt-core
|
|
5
5
|
Project-URL: Homepage, https://github.com/dbt-labs/dbt-adapters
|
|
6
6
|
Project-URL: Documentation, https://docs.getdbt.com
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "1.0.8b3"
|
|
@@ -18,9 +18,9 @@ from typing import (
|
|
|
18
18
|
Tuple,
|
|
19
19
|
Type,
|
|
20
20
|
Union,
|
|
21
|
+
TYPE_CHECKING,
|
|
21
22
|
)
|
|
22
23
|
|
|
23
|
-
import agate
|
|
24
24
|
from dbt_common.events.contextvars import get_node_info
|
|
25
25
|
from dbt_common.events.functions import fire_event
|
|
26
26
|
from dbt_common.exceptions import DbtInternalError, NotImplementedError
|
|
@@ -48,6 +48,9 @@ from dbt.adapters.events.types import (
|
|
|
48
48
|
)
|
|
49
49
|
from dbt.adapters.exceptions import FailedToConnectError, InvalidConnectionError
|
|
50
50
|
|
|
51
|
+
if TYPE_CHECKING:
|
|
52
|
+
import agate
|
|
53
|
+
|
|
51
54
|
|
|
52
55
|
SleepTime = Union[int, float] # As taken by time.sleep.
|
|
53
56
|
AdapterHandle = Any # Adapter connection handle objects can be any class.
|
|
@@ -162,9 +165,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
|
|
|
162
165
|
conn.handle = LazyHandle(self.open)
|
|
163
166
|
# Add the connection to thread_connections for this thread
|
|
164
167
|
self.set_thread_connection(conn)
|
|
165
|
-
fire_event(
|
|
166
|
-
NewConnection(conn_name=conn_name, conn_type=self.TYPE, node_info=get_node_info())
|
|
167
|
-
)
|
|
168
|
+
fire_event(NewConnection(conn_name=conn_name, conn_type=self.TYPE, node_info=get_node_info()))
|
|
168
169
|
else: # existing connection either wasn't open or didn't have the right name
|
|
169
170
|
if conn.state != "open":
|
|
170
171
|
conn.handle = LazyHandle(self.open)
|
|
@@ -396,7 +397,7 @@ class BaseConnectionManager(metaclass=abc.ABCMeta):
|
|
|
396
397
|
auto_begin: bool = False,
|
|
397
398
|
fetch: bool = False,
|
|
398
399
|
limit: Optional[int] = None,
|
|
399
|
-
) -> Tuple[AdapterResponse, agate.Table]:
|
|
400
|
+
) -> Tuple[AdapterResponse, "agate.Table"]:
|
|
400
401
|
"""Execute the given SQL.
|
|
401
402
|
|
|
402
403
|
:param str sql: The sql to execute.
|
|
@@ -20,16 +20,9 @@ from typing import (
|
|
|
20
20
|
Type,
|
|
21
21
|
TypedDict,
|
|
22
22
|
Union,
|
|
23
|
+
TYPE_CHECKING,
|
|
23
24
|
)
|
|
24
25
|
|
|
25
|
-
import agate
|
|
26
|
-
from dbt_common.clients.agate_helper import (
|
|
27
|
-
Integer,
|
|
28
|
-
empty_table,
|
|
29
|
-
get_column_value_uncased,
|
|
30
|
-
merge_tables,
|
|
31
|
-
table_from_rows,
|
|
32
|
-
)
|
|
33
26
|
from dbt_common.clients.jinja import CallableMacroGenerator
|
|
34
27
|
from dbt_common.contracts.constraints import (
|
|
35
28
|
ColumnLevelConstraint,
|
|
@@ -94,6 +87,9 @@ from dbt.adapters.exceptions import (
|
|
|
94
87
|
)
|
|
95
88
|
from dbt.adapters.protocol import AdapterConfig, MacroContextGeneratorCallable
|
|
96
89
|
|
|
90
|
+
if TYPE_CHECKING:
|
|
91
|
+
import agate
|
|
92
|
+
|
|
97
93
|
|
|
98
94
|
GET_CATALOG_MACRO_NAME = "get_catalog"
|
|
99
95
|
GET_CATALOG_RELATIONS_MACRO_NAME = "get_catalog_relations"
|
|
@@ -107,7 +103,14 @@ class ConstraintSupport(str, Enum):
|
|
|
107
103
|
NOT_SUPPORTED = "not_supported"
|
|
108
104
|
|
|
109
105
|
|
|
110
|
-
def
|
|
106
|
+
def _parse_callback_empty_table(*args, **kwargs) -> Tuple[str, "agate.Table"]:
|
|
107
|
+
# Lazy load agate_helper to avoid importing agate when it is not necessary.
|
|
108
|
+
from dbt_common.clients.agate_helper import empty_table
|
|
109
|
+
|
|
110
|
+
return "", empty_table()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _expect_row_value(key: str, row: "agate.Row"):
|
|
111
114
|
if key not in row.keys():
|
|
112
115
|
raise DbtInternalError(
|
|
113
116
|
'Got a row without "{}" column, columns: {}'.format(key, row.keys())
|
|
@@ -117,13 +120,13 @@ def _expect_row_value(key: str, row: agate.Row):
|
|
|
117
120
|
|
|
118
121
|
def _catalog_filter_schemas(
|
|
119
122
|
used_schemas: FrozenSet[Tuple[str, str]]
|
|
120
|
-
) -> Callable[[agate.Row], bool]:
|
|
123
|
+
) -> Callable[["agate.Row"], bool]:
|
|
121
124
|
"""Return a function that takes a row and decides if the row should be
|
|
122
125
|
included in the catalog output.
|
|
123
126
|
"""
|
|
124
127
|
schemas = frozenset((d.lower(), s.lower()) for d, s in used_schemas)
|
|
125
128
|
|
|
126
|
-
def test(row: agate.Row) -> bool:
|
|
129
|
+
def test(row: "agate.Row") -> bool:
|
|
127
130
|
table_database = _expect_row_value("table_database", row)
|
|
128
131
|
table_schema = _expect_row_value("table_schema", row)
|
|
129
132
|
# the schema may be present but None, which is not an error and should
|
|
@@ -254,6 +257,8 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
254
257
|
ConstraintType.foreign_key: ConstraintSupport.ENFORCED,
|
|
255
258
|
}
|
|
256
259
|
|
|
260
|
+
MAX_SCHEMA_METADATA_RELATIONS = 100
|
|
261
|
+
|
|
257
262
|
# This static member variable can be overriden in concrete adapter
|
|
258
263
|
# implementations to indicate adapter support for optional capabilities.
|
|
259
264
|
_capabilities = CapabilityDict({})
|
|
@@ -323,14 +328,14 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
323
328
|
if self.connections.query_header is not None:
|
|
324
329
|
self.connections.query_header.reset()
|
|
325
330
|
|
|
326
|
-
@available.parse(
|
|
331
|
+
@available.parse(_parse_callback_empty_table)
|
|
327
332
|
def execute(
|
|
328
333
|
self,
|
|
329
334
|
sql: str,
|
|
330
335
|
auto_begin: bool = False,
|
|
331
336
|
fetch: bool = False,
|
|
332
337
|
limit: Optional[int] = None,
|
|
333
|
-
) -> Tuple[AdapterResponse, agate.Table]:
|
|
338
|
+
) -> Tuple[AdapterResponse, "agate.Table"]:
|
|
334
339
|
"""Execute the given SQL. This is a thin wrapper around
|
|
335
340
|
ConnectionManager.execute.
|
|
336
341
|
|
|
@@ -340,7 +345,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
340
345
|
:param bool fetch: If set, fetch results.
|
|
341
346
|
:param Optional[int] limit: If set, only fetch n number of rows
|
|
342
347
|
:return: A tuple of the query status and results (empty if fetch=False).
|
|
343
|
-
:rtype: Tuple[AdapterResponse, agate.Table]
|
|
348
|
+
:rtype: Tuple[AdapterResponse, "agate.Table"]
|
|
344
349
|
"""
|
|
345
350
|
return self.connections.execute(sql=sql, auto_begin=auto_begin, fetch=fetch, limit=limit)
|
|
346
351
|
|
|
@@ -368,8 +373,8 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
368
373
|
]
|
|
369
374
|
return columns
|
|
370
375
|
|
|
371
|
-
@available.parse(
|
|
372
|
-
def get_partitions_metadata(self, table: str) -> Tuple[agate.Table]:
|
|
376
|
+
@available.parse(_parse_callback_empty_table)
|
|
377
|
+
def get_partitions_metadata(self, table: str) -> Tuple["agate.Table"]:
|
|
373
378
|
"""
|
|
374
379
|
TODO: Can we move this to dbt-bigquery?
|
|
375
380
|
Obtain partitions metadata for a BigQuery partitioned table.
|
|
@@ -377,7 +382,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
377
382
|
:param str table: a partitioned table id, in standard SQL format.
|
|
378
383
|
:return: a partition metadata tuple, as described in
|
|
379
384
|
https://cloud.google.com/bigquery/docs/creating-partitioned-tables#getting_partition_metadata_using_meta_tables.
|
|
380
|
-
:rtype: agate.Table
|
|
385
|
+
:rtype: "agate.Table"
|
|
381
386
|
"""
|
|
382
387
|
if hasattr(self.connections, "get_partitions_metadata"):
|
|
383
388
|
return self.connections.get_partitions_metadata(table=table)
|
|
@@ -421,7 +426,9 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
421
426
|
populate.
|
|
422
427
|
"""
|
|
423
428
|
return {
|
|
424
|
-
self.Relation.create_from(
|
|
429
|
+
self.Relation.create_from(
|
|
430
|
+
quoting=self.config, relation_config=relation_config
|
|
431
|
+
).without_identifier()
|
|
425
432
|
for relation_config in relation_configs
|
|
426
433
|
}
|
|
427
434
|
|
|
@@ -663,7 +670,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
663
670
|
# Methods about grants
|
|
664
671
|
###
|
|
665
672
|
@available
|
|
666
|
-
def standardize_grants_dict(self, grants_table: agate.Table) -> dict:
|
|
673
|
+
def standardize_grants_dict(self, grants_table: "agate.Table") -> dict:
|
|
667
674
|
"""Translate the result of `show grants` (or equivalent) to match the
|
|
668
675
|
grants which a user would configure in their project.
|
|
669
676
|
|
|
@@ -938,7 +945,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
938
945
|
###
|
|
939
946
|
@classmethod
|
|
940
947
|
@abc.abstractmethod
|
|
941
|
-
def convert_text_type(cls, agate_table: agate.Table, col_idx: int) -> str:
|
|
948
|
+
def convert_text_type(cls, agate_table: "agate.Table", col_idx: int) -> str:
|
|
942
949
|
"""Return the type in the database that best maps to the agate.Text
|
|
943
950
|
type for the given agate table and column index.
|
|
944
951
|
|
|
@@ -950,7 +957,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
950
957
|
|
|
951
958
|
@classmethod
|
|
952
959
|
@abc.abstractmethod
|
|
953
|
-
def convert_number_type(cls, agate_table: agate.Table, col_idx: int) -> str:
|
|
960
|
+
def convert_number_type(cls, agate_table: "agate.Table", col_idx: int) -> str:
|
|
954
961
|
"""Return the type in the database that best maps to the agate.Number
|
|
955
962
|
type for the given agate table and column index.
|
|
956
963
|
|
|
@@ -961,7 +968,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
961
968
|
raise NotImplementedError("`convert_number_type` is not implemented for this adapter!")
|
|
962
969
|
|
|
963
970
|
@classmethod
|
|
964
|
-
def convert_integer_type(cls, agate_table: agate.Table, col_idx: int) -> str:
|
|
971
|
+
def convert_integer_type(cls, agate_table: "agate.Table", col_idx: int) -> str:
|
|
965
972
|
"""Return the type in the database that best maps to the agate.Number
|
|
966
973
|
type for the given agate table and column index.
|
|
967
974
|
|
|
@@ -973,7 +980,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
973
980
|
|
|
974
981
|
@classmethod
|
|
975
982
|
@abc.abstractmethod
|
|
976
|
-
def convert_boolean_type(cls, agate_table: agate.Table, col_idx: int) -> str:
|
|
983
|
+
def convert_boolean_type(cls, agate_table: "agate.Table", col_idx: int) -> str:
|
|
977
984
|
"""Return the type in the database that best maps to the agate.Boolean
|
|
978
985
|
type for the given agate table and column index.
|
|
979
986
|
|
|
@@ -985,7 +992,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
985
992
|
|
|
986
993
|
@classmethod
|
|
987
994
|
@abc.abstractmethod
|
|
988
|
-
def convert_datetime_type(cls, agate_table: agate.Table, col_idx: int) -> str:
|
|
995
|
+
def convert_datetime_type(cls, agate_table: "agate.Table", col_idx: int) -> str:
|
|
989
996
|
"""Return the type in the database that best maps to the agate.DateTime
|
|
990
997
|
type for the given agate table and column index.
|
|
991
998
|
|
|
@@ -997,7 +1004,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
997
1004
|
|
|
998
1005
|
@classmethod
|
|
999
1006
|
@abc.abstractmethod
|
|
1000
|
-
def convert_date_type(cls, agate_table: agate.Table, col_idx: int) -> str:
|
|
1007
|
+
def convert_date_type(cls, agate_table: "agate.Table", col_idx: int) -> str:
|
|
1001
1008
|
"""Return the type in the database that best maps to the agate.Date
|
|
1002
1009
|
type for the given agate table and column index.
|
|
1003
1010
|
|
|
@@ -1009,7 +1016,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1009
1016
|
|
|
1010
1017
|
@classmethod
|
|
1011
1018
|
@abc.abstractmethod
|
|
1012
|
-
def convert_time_type(cls, agate_table: agate.Table, col_idx: int) -> str:
|
|
1019
|
+
def convert_time_type(cls, agate_table: "agate.Table", col_idx: int) -> str:
|
|
1013
1020
|
"""Return the type in the database that best maps to the
|
|
1014
1021
|
agate.TimeDelta type for the given agate table and column index.
|
|
1015
1022
|
|
|
@@ -1021,11 +1028,14 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1021
1028
|
|
|
1022
1029
|
@available
|
|
1023
1030
|
@classmethod
|
|
1024
|
-
def convert_type(cls, agate_table: agate.Table, col_idx: int) -> Optional[str]:
|
|
1031
|
+
def convert_type(cls, agate_table: "agate.Table", col_idx: int) -> Optional[str]:
|
|
1025
1032
|
return cls.convert_agate_type(agate_table, col_idx)
|
|
1026
1033
|
|
|
1027
1034
|
@classmethod
|
|
1028
|
-
def convert_agate_type(cls, agate_table: agate.Table, col_idx: int) -> Optional[str]:
|
|
1035
|
+
def convert_agate_type(cls, agate_table: "agate.Table", col_idx: int) -> Optional[str]:
|
|
1036
|
+
import agate
|
|
1037
|
+
from dbt_common.clients.agate_helper import Integer
|
|
1038
|
+
|
|
1029
1039
|
agate_type: Type = agate_table.column_types[col_idx]
|
|
1030
1040
|
conversions: List[Tuple[Type, Callable[..., str]]] = [
|
|
1031
1041
|
(Integer, cls.convert_integer_type),
|
|
@@ -1052,6 +1062,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1052
1062
|
project: Optional[str] = None,
|
|
1053
1063
|
context_override: Optional[Dict[str, Any]] = None,
|
|
1054
1064
|
kwargs: Optional[Dict[str, Any]] = None,
|
|
1065
|
+
needs_conn: bool = False,
|
|
1055
1066
|
) -> AttrDict:
|
|
1056
1067
|
"""Look macro_name up in the manifest and execute its results.
|
|
1057
1068
|
|
|
@@ -1064,6 +1075,10 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1064
1075
|
execution context.
|
|
1065
1076
|
:param kwargs: An optional dict of keyword args used to pass to the
|
|
1066
1077
|
macro.
|
|
1078
|
+
: param needs_conn: A boolean that indicates whether the specified macro
|
|
1079
|
+
requires an open connection to execute. If needs_conn is True, a
|
|
1080
|
+
connection is expected and opened if necessary. Otherwise (and by default),
|
|
1081
|
+
no connection is expected prior to executing the macro.
|
|
1067
1082
|
"""
|
|
1068
1083
|
|
|
1069
1084
|
if kwargs is None:
|
|
@@ -1096,17 +1111,23 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1096
1111
|
|
|
1097
1112
|
macro_function = CallableMacroGenerator(macro, macro_context)
|
|
1098
1113
|
|
|
1114
|
+
if needs_conn:
|
|
1115
|
+
connection = self.connections.get_thread_connection()
|
|
1116
|
+
self.connections.open(connection)
|
|
1117
|
+
|
|
1099
1118
|
with self.connections.exception_handler(f"macro {macro_name}"):
|
|
1100
1119
|
result = macro_function(**kwargs)
|
|
1101
1120
|
return result
|
|
1102
1121
|
|
|
1103
1122
|
@classmethod
|
|
1104
1123
|
def _catalog_filter_table(
|
|
1105
|
-
cls, table: agate.Table, used_schemas: FrozenSet[Tuple[str, str]]
|
|
1106
|
-
) -> agate.Table:
|
|
1124
|
+
cls, table: "agate.Table", used_schemas: FrozenSet[Tuple[str, str]]
|
|
1125
|
+
) -> "agate.Table":
|
|
1107
1126
|
"""Filter the table as appropriate for catalog entries. Subclasses can
|
|
1108
1127
|
override this to change filtering rules on a per-adapter basis.
|
|
1109
1128
|
"""
|
|
1129
|
+
from dbt_common.clients.agate_helper import table_from_rows
|
|
1130
|
+
|
|
1110
1131
|
# force database + schema to be strings
|
|
1111
1132
|
table = table_from_rows(
|
|
1112
1133
|
table.rows,
|
|
@@ -1120,7 +1141,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1120
1141
|
information_schema: InformationSchema,
|
|
1121
1142
|
schemas: Set[str],
|
|
1122
1143
|
used_schemas: FrozenSet[Tuple[str, str]],
|
|
1123
|
-
) -> agate.Table:
|
|
1144
|
+
) -> "agate.Table":
|
|
1124
1145
|
kwargs = {"information_schema": information_schema, "schemas": schemas}
|
|
1125
1146
|
table = self.execute_macro(GET_CATALOG_MACRO_NAME, kwargs=kwargs)
|
|
1126
1147
|
|
|
@@ -1132,7 +1153,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1132
1153
|
information_schema: InformationSchema,
|
|
1133
1154
|
relations: List[BaseRelation],
|
|
1134
1155
|
used_schemas: FrozenSet[Tuple[str, str]],
|
|
1135
|
-
) -> agate.Table:
|
|
1156
|
+
) -> "agate.Table":
|
|
1136
1157
|
kwargs = {
|
|
1137
1158
|
"information_schema": information_schema,
|
|
1138
1159
|
"relations": relations,
|
|
@@ -1148,10 +1169,10 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1148
1169
|
used_schemas: FrozenSet[Tuple[str, str]],
|
|
1149
1170
|
relations: Optional[Set[BaseRelation]] = None,
|
|
1150
1171
|
):
|
|
1151
|
-
catalogs: agate.Table
|
|
1172
|
+
catalogs: "agate.Table"
|
|
1152
1173
|
if (
|
|
1153
1174
|
relations is None
|
|
1154
|
-
or len(relations) >
|
|
1175
|
+
or len(relations) > self.MAX_SCHEMA_METADATA_RELATIONS
|
|
1155
1176
|
or not self.supports(Capability.SchemaMetadataByRelations)
|
|
1156
1177
|
):
|
|
1157
1178
|
# Do it the traditional way. We get the full catalog.
|
|
@@ -1171,7 +1192,7 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1171
1192
|
for r in relations
|
|
1172
1193
|
}
|
|
1173
1194
|
|
|
1174
|
-
def in_map(row: agate.Row):
|
|
1195
|
+
def in_map(row: "agate.Row"):
|
|
1175
1196
|
d = _expect_row_value("table_database", row)
|
|
1176
1197
|
s = _expect_row_value("table_schema", row)
|
|
1177
1198
|
i = _expect_row_value("table_name", row)
|
|
@@ -1184,16 +1205,16 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1184
1205
|
|
|
1185
1206
|
return catalogs, exceptions
|
|
1186
1207
|
|
|
1187
|
-
def row_matches_relation(self, row: agate.Row, relations: Set[BaseRelation]):
|
|
1208
|
+
def row_matches_relation(self, row: "agate.Row", relations: Set[BaseRelation]):
|
|
1188
1209
|
pass
|
|
1189
1210
|
|
|
1190
1211
|
def get_catalog(
|
|
1191
1212
|
self,
|
|
1192
1213
|
relation_configs: Iterable[RelationConfig],
|
|
1193
1214
|
used_schemas: FrozenSet[Tuple[str, str]],
|
|
1194
|
-
) -> Tuple[agate.Table, List[Exception]]:
|
|
1215
|
+
) -> Tuple["agate.Table", List[Exception]]:
|
|
1195
1216
|
with executor(self.config) as tpe:
|
|
1196
|
-
futures: List[Future[agate.Table]] = []
|
|
1217
|
+
futures: List[Future["agate.Table"]] = []
|
|
1197
1218
|
schema_map: SchemaSearchMap = self._get_catalog_schemas(relation_configs)
|
|
1198
1219
|
for info, schemas in schema_map.items():
|
|
1199
1220
|
if len(schemas) == 0:
|
|
@@ -1209,9 +1230,9 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1209
1230
|
|
|
1210
1231
|
def get_catalog_by_relations(
|
|
1211
1232
|
self, used_schemas: FrozenSet[Tuple[str, str]], relations: Set[BaseRelation]
|
|
1212
|
-
) -> Tuple[agate.Table, List[Exception]]:
|
|
1233
|
+
) -> Tuple["agate.Table", List[Exception]]:
|
|
1213
1234
|
with executor(self.config) as tpe:
|
|
1214
|
-
futures: List[Future[agate.Table]] = []
|
|
1235
|
+
futures: List[Future["agate.Table"]] = []
|
|
1215
1236
|
relations_by_schema = self._get_catalog_relations_by_info_schema(relations)
|
|
1216
1237
|
for info_schema in relations_by_schema:
|
|
1217
1238
|
name = ".".join([str(info_schema.database), "information_schema"])
|
|
@@ -1241,6 +1262,8 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1241
1262
|
macro_resolver: Optional[MacroResolverProtocol] = None,
|
|
1242
1263
|
) -> Tuple[Optional[AdapterResponse], FreshnessResponse]:
|
|
1243
1264
|
"""Calculate the freshness of sources in dbt, and return it"""
|
|
1265
|
+
import agate
|
|
1266
|
+
|
|
1244
1267
|
kwargs: Dict[str, Any] = {
|
|
1245
1268
|
"source": source,
|
|
1246
1269
|
"loaded_at_field": loaded_at_field,
|
|
@@ -1251,8 +1274,8 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1251
1274
|
# in older versions of dbt-core, the 'collect_freshness' macro returned the table of results directly
|
|
1252
1275
|
# starting in v1.5, by default, we return both the table and the adapter response (metadata about the query)
|
|
1253
1276
|
result: Union[
|
|
1254
|
-
AttrDict, # current: contains AdapterResponse + agate.Table
|
|
1255
|
-
agate.Table, # previous: just table
|
|
1277
|
+
AttrDict, # current: contains AdapterResponse + "agate.Table"
|
|
1278
|
+
"agate.Table", # previous: just table
|
|
1256
1279
|
]
|
|
1257
1280
|
result = self.execute_macro(
|
|
1258
1281
|
FRESHNESS_MACRO_NAME, kwargs=kwargs, macro_resolver=macro_resolver
|
|
@@ -1283,46 +1306,110 @@ class BaseAdapter(metaclass=AdapterMeta):
|
|
|
1283
1306
|
}
|
|
1284
1307
|
return adapter_response, freshness
|
|
1285
1308
|
|
|
1309
|
+
def calculate_freshness_from_metadata_batch(
|
|
1310
|
+
self,
|
|
1311
|
+
sources: List[BaseRelation],
|
|
1312
|
+
macro_resolver: Optional[MacroResolverProtocol] = None,
|
|
1313
|
+
) -> Tuple[List[Optional[AdapterResponse]], Dict[BaseRelation, FreshnessResponse]]:
|
|
1314
|
+
"""
|
|
1315
|
+
Given a list of sources (BaseRelations), calculate the metadata-based freshness in batch.
|
|
1316
|
+
This method should _not_ execute a warehouse query per source, but rather batch up
|
|
1317
|
+
the sources into as few requests as possible to minimize the number of roundtrips required
|
|
1318
|
+
to compute metadata-based freshness for each input source.
|
|
1319
|
+
|
|
1320
|
+
:param sources: The list of sources to calculate metadata-based freshness for
|
|
1321
|
+
:param macro_resolver: An optional macro_resolver to use for get_relation_last_modified
|
|
1322
|
+
:return: a tuple where:
|
|
1323
|
+
* the first element is a list of optional AdapterResponses indicating the response
|
|
1324
|
+
for each request the method made to compute the freshness for the provided sources.
|
|
1325
|
+
* the second element is a dictionary mapping an input source BaseRelation to a FreshnessResponse,
|
|
1326
|
+
if it was possible to calculate a FreshnessResponse for the source.
|
|
1327
|
+
"""
|
|
1328
|
+
# Track schema, identifiers of sources for lookup from batch query
|
|
1329
|
+
schema_identifier_to_source = {
|
|
1330
|
+
(
|
|
1331
|
+
source.path.get_lowered_part(ComponentName.Schema),
|
|
1332
|
+
source.path.get_lowered_part(ComponentName.Identifier),
|
|
1333
|
+
): source
|
|
1334
|
+
for source in sources
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
# Group metadata sources by information schema -- one query per information schema will be necessary
|
|
1338
|
+
sources_by_info_schema: Dict[InformationSchema, List[BaseRelation]] = self._get_catalog_relations_by_info_schema(sources)
|
|
1339
|
+
|
|
1340
|
+
freshness_responses: Dict[BaseRelation, FreshnessResponse] = {}
|
|
1341
|
+
adapter_responses: List[Optional[AdapterResponse]] = []
|
|
1342
|
+
for (
|
|
1343
|
+
information_schema,
|
|
1344
|
+
sources_for_information_schema,
|
|
1345
|
+
) in sources_by_info_schema.items():
|
|
1346
|
+
result = self.execute_macro(
|
|
1347
|
+
GET_RELATION_LAST_MODIFIED_MACRO_NAME,
|
|
1348
|
+
kwargs={
|
|
1349
|
+
"information_schema": information_schema,
|
|
1350
|
+
"relations": sources_for_information_schema,
|
|
1351
|
+
},
|
|
1352
|
+
macro_resolver=macro_resolver,
|
|
1353
|
+
needs_conn=True,
|
|
1354
|
+
)
|
|
1355
|
+
adapter_response, table = result.response, result.table # type: ignore[attr-defined]
|
|
1356
|
+
adapter_responses.append(adapter_response)
|
|
1357
|
+
|
|
1358
|
+
for row in table:
|
|
1359
|
+
raw_relation, freshness_response = self._parse_freshness_row(row, table)
|
|
1360
|
+
source_relation_for_result = schema_identifier_to_source[raw_relation]
|
|
1361
|
+
freshness_responses[source_relation_for_result] = freshness_response
|
|
1362
|
+
|
|
1363
|
+
return adapter_responses, freshness_responses
|
|
1364
|
+
|
|
1286
1365
|
def calculate_freshness_from_metadata(
|
|
1287
1366
|
self,
|
|
1288
1367
|
source: BaseRelation,
|
|
1289
1368
|
macro_resolver: Optional[MacroResolverProtocol] = None,
|
|
1290
1369
|
) -> Tuple[Optional[AdapterResponse], FreshnessResponse]:
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
"relations": [source],
|
|
1294
|
-
}
|
|
1295
|
-
result = self.execute_macro(
|
|
1296
|
-
GET_RELATION_LAST_MODIFIED_MACRO_NAME,
|
|
1297
|
-
kwargs=kwargs,
|
|
1370
|
+
adapter_responses, freshness_responses = self.calculate_freshness_from_metadata_batch(
|
|
1371
|
+
sources=[source],
|
|
1298
1372
|
macro_resolver=macro_resolver,
|
|
1299
1373
|
)
|
|
1300
|
-
adapter_response
|
|
1374
|
+
adapter_response = adapter_responses[0] if adapter_responses else None
|
|
1375
|
+
return adapter_response, freshness_responses[source]
|
|
1301
1376
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
except Exception:
|
|
1307
|
-
raise MacroResultError(GET_RELATION_LAST_MODIFIED_MACRO_NAME, table)
|
|
1308
|
-
|
|
1309
|
-
if last_modified_val is None:
|
|
1377
|
+
def _create_freshness_response(
|
|
1378
|
+
self, last_modified: Optional[datetime], snapshotted_at: Optional[datetime]
|
|
1379
|
+
) -> FreshnessResponse:
|
|
1380
|
+
if last_modified is None:
|
|
1310
1381
|
# Interpret missing value as "infinitely long ago"
|
|
1311
1382
|
max_loaded_at = datetime(1, 1, 1, 0, 0, 0, tzinfo=pytz.UTC)
|
|
1312
1383
|
else:
|
|
1313
|
-
max_loaded_at = _utc(
|
|
1314
|
-
|
|
1315
|
-
snapshotted_at = _utc(snapshotted_at_val, None, "snapshotted_at")
|
|
1384
|
+
max_loaded_at = _utc(last_modified, None, "last_modified")
|
|
1316
1385
|
|
|
1386
|
+
snapshotted_at = _utc(snapshotted_at, None, "snapshotted_at")
|
|
1317
1387
|
age = (snapshotted_at - max_loaded_at).total_seconds()
|
|
1318
|
-
|
|
1319
1388
|
freshness: FreshnessResponse = {
|
|
1320
1389
|
"max_loaded_at": max_loaded_at,
|
|
1321
1390
|
"snapshotted_at": snapshotted_at,
|
|
1322
1391
|
"age": age,
|
|
1323
1392
|
}
|
|
1324
1393
|
|
|
1325
|
-
return
|
|
1394
|
+
return freshness
|
|
1395
|
+
|
|
1396
|
+
def _parse_freshness_row(self, row: "agate.Row", table: "agate.Table") -> Tuple[Any, FreshnessResponse]:
|
|
1397
|
+
from dbt_common.clients.agate_helper import get_column_value_uncased
|
|
1398
|
+
|
|
1399
|
+
try:
|
|
1400
|
+
last_modified_val = get_column_value_uncased("last_modified", row)
|
|
1401
|
+
snapshotted_at_val = get_column_value_uncased("snapshotted_at", row)
|
|
1402
|
+
identifier = get_column_value_uncased("identifier", row)
|
|
1403
|
+
schema = get_column_value_uncased("schema", row)
|
|
1404
|
+
except Exception:
|
|
1405
|
+
raise MacroResultError(GET_RELATION_LAST_MODIFIED_MACRO_NAME, table)
|
|
1406
|
+
|
|
1407
|
+
freshness_response = self._create_freshness_response(
|
|
1408
|
+
last_modified_val,
|
|
1409
|
+
snapshotted_at_val
|
|
1410
|
+
)
|
|
1411
|
+
raw_relation = schema.lower().strip(), identifier.lower().strip()
|
|
1412
|
+
return raw_relation, freshness_response
|
|
1326
1413
|
|
|
1327
1414
|
def pre_model_hook(self, config: Mapping[str, Any]) -> Any:
|
|
1328
1415
|
"""A hook for running some operation before the model materialization
|
|
@@ -1636,10 +1723,12 @@ join diff_count using (id)
|
|
|
1636
1723
|
|
|
1637
1724
|
|
|
1638
1725
|
def catch_as_completed(
|
|
1639
|
-
futures, # typing: List[Future[agate.Table]]
|
|
1640
|
-
) -> Tuple[agate.Table, List[Exception]]:
|
|
1641
|
-
|
|
1642
|
-
|
|
1726
|
+
futures, # typing: List[Future["agate.Table"]]
|
|
1727
|
+
) -> Tuple["agate.Table", List[Exception]]:
|
|
1728
|
+
from dbt_common.clients.agate_helper import merge_tables
|
|
1729
|
+
|
|
1730
|
+
# catalogs: "agate.Table" =".Table(rows=[])
|
|
1731
|
+
tables: List["agate.Table"] = []
|
|
1643
1732
|
exceptions: List[Exception] = []
|
|
1644
1733
|
|
|
1645
1734
|
for future in as_completed(futures):
|
|
@@ -52,13 +52,13 @@ class BaseRelation(FakeAPIObject, Hashable):
|
|
|
52
52
|
# adding a relation type here also requires defining the associated rename macro
|
|
53
53
|
# e.g. adding RelationType.View in dbt-postgres requires that you define:
|
|
54
54
|
# include/postgres/macros/relations/view/rename.sql::postgres__get_rename_view_sql()
|
|
55
|
-
renameable_relations: SerializableIterable = ()
|
|
55
|
+
renameable_relations: SerializableIterable = field(default_factory=frozenset)
|
|
56
56
|
|
|
57
57
|
# register relation types that are atomically replaceable, e.g. they have "create or replace" syntax
|
|
58
58
|
# adding a relation type here also requires defining the associated replace macro
|
|
59
59
|
# e.g. adding RelationType.View in dbt-postgres requires that you define:
|
|
60
60
|
# include/postgres/macros/relations/view/replace.sql::postgres__get_replace_view_sql()
|
|
61
|
-
replaceable_relations: SerializableIterable = ()
|
|
61
|
+
replaceable_relations: SerializableIterable = field(default_factory=frozenset)
|
|
62
62
|
|
|
63
63
|
def _is_exactish_match(self, field: ComponentName, value: str) -> bool:
|
|
64
64
|
if self.dbt_created and self.quote_policy.get_part(field) is False:
|
|
@@ -13,6 +13,9 @@ class Capability(str, Enum):
|
|
|
13
13
|
TableLastModifiedMetadata = "TableLastModifiedMetadata"
|
|
14
14
|
"""Indicates support for determining the time of the last table modification by querying database metadata."""
|
|
15
15
|
|
|
16
|
+
TableLastModifiedMetadataBatch = "TableLastModifiedMetadataBatch"
|
|
17
|
+
"""Indicates support for performantly determining the time of the last table modification by querying database metadata in batch."""
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
class Support(str, Enum):
|
|
18
21
|
Unknown = "Unknown"
|
|
@@ -48,11 +48,15 @@ class MaterializationConfig(Mapping, ABC):
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
class RelationConfig(Protocol):
|
|
51
|
+
resource_type: str
|
|
51
52
|
name: str
|
|
53
|
+
description: str
|
|
52
54
|
database: str
|
|
53
55
|
schema: str
|
|
54
56
|
identifier: str
|
|
55
57
|
compiled_code: Optional[str]
|
|
58
|
+
meta: Dict[str, Any]
|
|
59
|
+
tags: List[str]
|
|
56
60
|
quoting_dict: Dict[str, bool]
|
|
57
61
|
config: Optional[MaterializationConfig]
|
|
58
62
|
|
|
@@ -515,3 +515,13 @@ message ConstraintNotSupportedMsg {
|
|
|
515
515
|
AdapterCommonEventInfo info = 1;
|
|
516
516
|
ConstraintNotSupported data = 2;
|
|
517
517
|
}
|
|
518
|
+
|
|
519
|
+
// E050
|
|
520
|
+
message TypeCodeNotFound {
|
|
521
|
+
int32 type_code = 1;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
message TypeCodeNotFoundMsg {
|
|
525
|
+
AdapterCommonEventInfo info = 1;
|
|
526
|
+
TypeCodeNotFound data = 2;
|
|
527
|
+
}
|