-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #92 from tekliner/BI-483-merge-fork-of-dbt-ch-conn…
…ector Adaptive materialization strategy when using Atomic schema engine
- Loading branch information
Showing
6 changed files
with
275 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ __pycache__/ | |
# Distribution / packaging | ||
.Python | ||
env*/ | ||
venv*/ | ||
dbt_env/ | ||
build/ | ||
develop-eggs/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
{% materialization table, adapter='clickhouse' %} | ||
{%- set identifier = model['alias'] -%} | ||
{%- set tmp_identifier = model['name'] + '__dbt_tmp' -%} | ||
{%- set backup_identifier = model['name'] + '__dbt_backup' -%} | ||
|
||
{%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%} | ||
{%- set target_relation = api.Relation.create(identifier=identifier, | ||
schema=schema, | ||
database=database, | ||
type='table') -%} | ||
{%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier, | ||
schema=schema, | ||
database=database, | ||
type='table') -%} | ||
-- the intermediate_relation should not already exist in the database; get_relation | ||
-- will return None in that case. Otherwise, we get a relation that we can drop | ||
-- later, before we try to use this name for the current operation | ||
{%- set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier, | ||
schema=schema, | ||
database=database) -%} | ||
/* | ||
See ../view/view.sql for more information about this relation. | ||
*/ | ||
{%- set backup_relation_type = 'table' if old_relation is none else old_relation.type -%} | ||
{%- set backup_relation = api.Relation.create(identifier=backup_identifier, | ||
schema=schema, | ||
database=database, | ||
type=backup_relation_type) -%} | ||
-- as above, the backup_relation should not already exist | ||
{%- set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier, | ||
schema=schema, | ||
database=database) -%} | ||
|
||
|
||
-- drop the temp relations if they exist already in the database | ||
{{ drop_relation_if_exists(preexisting_intermediate_relation) }} | ||
{{ drop_relation_if_exists(preexisting_backup_relation) }} | ||
|
||
{{ run_hooks(pre_hooks, inside_transaction=False) }} | ||
|
||
-- `BEGIN` happens here: | ||
{{ run_hooks(pre_hooks, inside_transaction=True) }} | ||
|
||
{% if is_atomic and old_relation is not none %} | ||
-- only makes sense to EXCHANGE when the relation already exists | ||
|
||
-- build model as backup_relation so it is saved after EXCHANGE | ||
{% call statement('main') -%} | ||
{{ get_create_table_as_sql(False, backup_relation, sql) }} | ||
{%- endcall %} | ||
|
||
{% do exchange_tables_atomic(backup_relation, old_relation) %} | ||
|
||
{% else %} | ||
|
||
-- build model | ||
{% call statement('main') -%} | ||
{{ get_create_table_as_sql(False, intermediate_relation, sql) }} | ||
{%- endcall %} | ||
|
||
-- cleanup, move the existing table out of the way and rename intermediate to target | ||
{% if old_relation is not none %} | ||
{{ adapter.rename_relation(old_relation, backup_relation) }} | ||
{% endif %} | ||
|
||
{{ adapter.rename_relation(intermediate_relation, target_relation) }} | ||
|
||
{% endif %} | ||
|
||
{% do create_indexes(target_relation) %} | ||
|
||
{{ run_hooks(post_hooks, inside_transaction=True) }} | ||
|
||
{% do persist_docs(target_relation, model) %} | ||
|
||
-- `COMMIT` happens here | ||
{{ adapter.commit() }} | ||
|
||
-- finally, drop the existing/backup relation after the commit | ||
{{ drop_relation_if_exists(backup_relation) }} | ||
|
||
{{ run_hooks(post_hooks, inside_transaction=False) }} | ||
|
||
{{ return({'relations': [target_relation]}) }} | ||
{% endmaterialization %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
{%- materialization view, adapter='clickhouse' -%} | ||
|
||
{%- set identifier = model['alias'] -%} | ||
{%- set tmp_identifier = model['name'] + '__dbt_tmp' -%} | ||
{%- set backup_identifier = model['name'] + '__dbt_backup' -%} | ||
|
||
{%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%} | ||
{%- set is_atomic = engine_exchange_support(old_relation) -%} | ||
|
||
{%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database, | ||
type='view') -%} | ||
{%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier, | ||
schema=schema, database=database, type='view') -%} | ||
-- the intermediate_relation should not already exist in the database; get_relation | ||
-- will return None in that case. Otherwise, we get a relation that we can drop | ||
-- later, before we try to use this name for the current operation | ||
{%- set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier, | ||
schema=schema, | ||
database=database) -%} | ||
/* | ||
This relation (probably) doesn't exist yet. If it does exist, it's a leftover from | ||
a previous run, and we're going to try to drop it immediately. At the end of this | ||
materialization, we're going to rename the "old_relation" to this identifier, | ||
and then we're going to drop it. In order to make sure we run the correct one of: | ||
- drop view ... | ||
- drop table ... | ||
We need to set the type of this relation to be the type of the old_relation, if it exists, | ||
or else "view" as a sane default if it does not. Note that if the old_relation does not | ||
exist, then there is nothing to move out of the way and subsequentally drop. In that case, | ||
this relation will be effectively unused. | ||
*/ | ||
{%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%} | ||
{%- set backup_relation = api.Relation.create(identifier=backup_identifier, | ||
schema=schema, database=database, | ||
type=backup_relation_type) -%} | ||
-- as above, the backup_relation should not already exist | ||
{%- set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier, | ||
schema=schema, | ||
database=database) -%} | ||
|
||
{{ run_hooks(pre_hooks, inside_transaction=False) }} | ||
|
||
-- drop the temp relations if they exist already in the database | ||
{{ drop_relation_if_exists(preexisting_intermediate_relation) }} | ||
{{ drop_relation_if_exists(preexisting_backup_relation) }} | ||
|
||
-- `BEGIN` happens here: | ||
{{ run_hooks(pre_hooks, inside_transaction=True) }} | ||
|
||
{% if is_atomic and old_relation is not none %} | ||
-- only makes sense to EXCHANGE when the relation already exists | ||
|
||
-- build model as backup_relation so it is saved after EXCHANGE | ||
{% call statement('main') -%} | ||
{{ create_view_as(backup_relation, sql) }} | ||
{%- endcall %} | ||
|
||
{% do exchange_tables_atomic(backup_relation, old_relation) %} | ||
|
||
{% else %} | ||
|
||
-- build model | ||
{% call statement('main') -%} | ||
{{ create_view_as(intermediate_relation, sql) }} | ||
{%- endcall %} | ||
|
||
-- cleanup, move the existing view out of the way and rename intermediate to target | ||
{% if old_relation is not none %} | ||
{{ adapter.rename_relation(old_relation, backup_relation) }} | ||
{% endif %} | ||
|
||
{{ adapter.rename_relation(intermediate_relation, target_relation) }} | ||
|
||
{% endif %} | ||
|
||
{% do persist_docs(target_relation, model) %} | ||
|
||
{{ run_hooks(post_hooks, inside_transaction=True) }} | ||
|
||
{{ adapter.commit() }} | ||
|
||
{{ drop_relation_if_exists(backup_relation) }} | ||
|
||
{{ run_hooks(post_hooks, inside_transaction=False) }} | ||
|
||
{{ return({'relations': [target_relation]}) }} | ||
|
||
{%- endmaterialization -%} |