diff --git a/plugins/bigquery/dbt/adapters/bigquery/impl.py b/plugins/bigquery/dbt/adapters/bigquery/impl.py index 9ba281227ef..fdf3c2f0374 100644 --- a/plugins/bigquery/dbt/adapters/bigquery/impl.py +++ b/plugins/bigquery/dbt/adapters/bigquery/impl.py @@ -83,6 +83,27 @@ def rename_relation(self, from_relation, to_relation): '`rename_relation` is not implemented for this adapter!' ) + @available.parse(lambda *a, **k: False) + def check_schema_exists(self, database: str, schema: str) -> bool: + conn = self.connections.get_thread_connection() + client = conn.handle + + bigquery_dataset = self.connections.dataset( + database, schema, conn + ) + # try to do things with the dataset. If it doesn't exist it will 404. + # we have to do it this way to handle underscore-prefixed datasets, + # which appear in neither the information_schema.schemata view nor the + # list_datasets method. + try: + next(client.list_tables(bigquery_dataset, max_results=1)) + except StopIteration: + pass + except google.api_core.exceptions.NotFound: + # the schema does not exist + return False + return True + def get_columns_in_relation(self, relation): try: table = self.connections.get_bq_table( diff --git a/plugins/bigquery/dbt/include/bigquery/macros/adapters.sql b/plugins/bigquery/dbt/include/bigquery/macros/adapters.sql index eb9f63c32be..9589f148ba7 100644 --- a/plugins/bigquery/dbt/include/bigquery/macros/adapters.sql +++ b/plugins/bigquery/dbt/include/bigquery/macros/adapters.sql @@ -105,45 +105,23 @@ {% endmacro %} -{%- macro bigquery_similar_schemas(database, schema) -%} - {%- set sql -%} - select distinct schema_name - from {{ information_schema_name(database) }}.SCHEMATA - where UPPER(catalog_name) like UPPER('{{ database }}') - and UPPER(schema_name) like UPPER('{{ schema }}') - {%- endset -%} - {%- set schemas = [] -%} - {%- for row in run_query(sql) -%} - {%- do schemas.append(row['schema_name']) %} - {%- endfor -%} - {{ return(schemas) }} -{%- endmacro -%} - - {% macro bigquery__list_relations_without_caching(information_schema, schema) -%} {# In bigquery, you can't query the full information schema, you can only do so by schema (so 'database.schema.information_schema.tables'). But our schema value is case-insensitive for annoying reasons involving quoting. So you have figure out what schemas match the given schema first, and query them each. #} - {%- set schema_candidates = bigquery_similar_schemas(information_schema.database, schema) -%} - {%- if (schema_candidates | length) == 0 -%} - {{ return(empty_table()) }} - {%- endif -%} {%- set query -%} - {%- for s in schema_candidates %} - select - table_catalog as database, - table_name as name, - table_schema as schema, - case when table_type = 'BASE TABLE' then 'table' - when table_type = 'VIEW' then 'view' - when table_type = 'EXTERNAL TABLE' then 'external' - else table_type - end as table_type - from {{ information_schema.replace(information_schema_view='TABLES') }} - {% if not loop.last %}union all{% endif %} - {%- endfor %} + select + table_catalog as database, + table_name as name, + table_schema as schema, + case when table_type = 'BASE TABLE' then 'table' + when table_type = 'VIEW' then 'view' + when table_type = 'EXTERNAL TABLE' then 'external' + else table_type + end as table_type + from {{ information_schema.replace(information_schema_view='TABLES') }} {%- endset -%} {{ return(run_query(query)) }} {%- endmacro %}