Skip to content

Commit 880dab9

Browse files
committed
Catalog generation fix and warning for database name
1 parent 4311eb5 commit 880dab9

File tree

4 files changed

+46
-32
lines changed

4 files changed

+46
-32
lines changed

dbt/adapters/oracle/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Copyright (c) 2022, Oracle and/or its affiliates.
2+
Copyright (c) 2024, Oracle and/or its affiliates.
33
Copyright (c) 2020, Vitor Avancini
44
55
Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,6 @@
1717
from dbt.adapters.oracle.connections import OracleAdapterConnectionManager
1818
from dbt.adapters.oracle.connections import OracleAdapterCredentials
1919
from dbt.adapters.oracle.impl import OracleAdapter
20-
2120
from dbt.adapters.base import AdapterPlugin
2221
from dbt.include import oracle
2322

dbt/adapters/oracle/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
1616
"""
17-
version = "1.7.14"
17+
version = "1.8.0"

dbt/adapters/oracle/connection_helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Copyright (c) 2023, Oracle and/or its affiliates.
2+
Copyright (c) 2024, Oracle and/or its affiliates.
33
Copyright (c) 2020, Vitor Avancini
44
55
Licensed under the Apache License, Version 2.0 (the "License");

dbt/adapters/oracle/impl.py

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from typing import (
1919
Optional, List, Set, FrozenSet, Tuple, Iterable
2020
)
21-
from itertools import chain
2221
from typing import (
2322
Any,
2423
Callable,
@@ -31,8 +30,9 @@
3130
from dbt_common.contracts.constraints import ConstraintType
3231
from dbt_common.utils import filter_null_values
3332

33+
from dbt.adapters.base.connections import Connection
3434
from dbt.adapters.base.relation import BaseRelation, InformationSchema
35-
from dbt.adapters.base.impl import GET_CATALOG_MACRO_NAME, ConstraintSupport, GET_CATALOG_RELATIONS_MACRO_NAME, _expect_row_value
35+
from dbt.adapters.base.impl import ConstraintSupport, GET_CATALOG_RELATIONS_MACRO_NAME, _expect_row_value
3636
from dbt.adapters.contracts.relation import RelationConfig
3737
from dbt.adapters.events.logging import AdapterLogger
3838
from dbt.adapters.sql import SQLAdapter
@@ -45,6 +45,8 @@
4545
from dbt.adapters.oracle.keyword_catalog import KEYWORDS
4646
from dbt.adapters.oracle.python_submissions import OracleADBSPythonJob
4747

48+
from dbt_common.ui import warning_tag, yellow
49+
4850
logger = AdapterLogger("oracle")
4951

5052
# Added 6 random hex letters (56c36b) to table_a and table_b to avoid ORA-32031.
@@ -81,6 +83,15 @@
8183
LIST_RELATIONS_MACRO_NAME = 'list_relations_without_caching'
8284
GET_DATABASE_MACRO_NAME = 'get_database_name'
8385

86+
MISSING_DATABASE_NAME_FOR_CATALOG_WARNING_MESSAGE = (
87+
"database key is missing from the target-profile in the file profiles.yml "
88+
"\n Starting with dbt-oracle 1.8 database name is needed for catalog generation "
89+
"\n Without database key in the target profile the generated catalog will be empty "
90+
"\n \t i.e. `dbt docs generate` command will generate an empty catalog json "
91+
"\n Make the following entry in dbt profile.yml file for the target profile "
92+
"\n database: {0}"
93+
)
94+
8495

8596
class OracleAdapter(SQLAdapter):
8697
ConnectionManager = OracleAdapterConnectionManager
@@ -137,7 +148,7 @@ def verify_database(self, database):
137148
if database.startswith('"'):
138149
database = database.strip('"')
139150
expected = self.config.credentials.database
140-
if expected and database.lower() != expected.lower():
151+
if expected and database.lower() != 'none' and database.lower() != expected.lower():
141152
raise dbt_common.exceptions.DbtRuntimeError(
142153
'Cross-db references not allowed in {} ({} vs {})'
143154
.format(self.type(), database, expected)
@@ -205,37 +216,18 @@ def get_relation(self, database: str, schema: str, identifier: str) -> Optional[
205216
database = self.config.credentials.database
206217
return super().get_relation(database, schema, identifier)
207218

208-
def _get_one_catalog(
219+
def _get_one_catalog_by_relations(
209220
self,
210221
information_schema: InformationSchema,
211-
schemas: Set[str],
222+
relations: List[BaseRelation],
212223
used_schemas: FrozenSet[Tuple[str, str]],
213-
) -> agate.Table:
214-
logger.info(f"GET ONE CATALOG =====> {schemas}")
215-
logger.info(f"GET ONE CATALOG =====> {information_schema}")
216-
logger.info(f"GET ONE CATALOG =====> {used_schemas}")
217-
kwargs = {"information_schema": information_schema, "schemas": schemas}
218-
table = self.execute_macro(GET_CATALOG_MACRO_NAME, kwargs=kwargs)
219-
results = self._catalog_filter_table(table, used_schemas=used_schemas)
220-
logger.info(f"GET ONE CATALOG =====> {results}")
221-
return results
222-
223-
def _get_one_catalog_by_relations(
224-
self,
225-
information_schema: InformationSchema,
226-
relations: List[BaseRelation],
227-
used_schemas: FrozenSet[Tuple[str, str]],
228-
) -> agate.Table:
229-
logger.info(f"GET ONE _get_one_catalog_by_relations =====> {relations}")
230-
logger.info(f"GET ONE _get_one_catalog_by_relations =====> {information_schema}")
231-
logger.info(f"GET ONE _get_one_catalog_by_relations =====> {used_schemas}")
224+
) -> "agate.Table":
232225
kwargs = {
233226
"information_schema": information_schema,
234227
"relations": relations,
235228
}
236229
table = self.execute_macro(GET_CATALOG_RELATIONS_MACRO_NAME, kwargs=kwargs)
237230
results = self._catalog_filter_table(table, used_schemas) # type: ignore[arg-type]
238-
logger.info(f"GET ONE _get_one_catalog_by_relations =====> {results}")
239231
return results
240232

241233
def get_filtered_catalog(
@@ -244,10 +236,21 @@ def get_filtered_catalog(
244236
used_schemas: FrozenSet[Tuple[str, str]],
245237
relations: Optional[Set[BaseRelation]] = None
246238
):
247-
logger.info(f"GET ONE get_filtered_catalog =====> {relations}")
248-
logger.info(f"GET ONE get_filtered_catalog =====> {relations}")
249-
logger.info(f"GET ONE get_filtered_catalog =====> {used_schemas}")
250239
catalogs: agate.Table
240+
241+
def is_database_none(database):
242+
return database is None or database == 'None'
243+
244+
def populate_database(database):
245+
if not is_database_none(database):
246+
return database
247+
return self.config.credentials.database
248+
249+
# In case database is not defined, we can use database set in credentials object
250+
if any(is_database_none(database) for database, schema in used_schemas):
251+
used_schemas = frozenset([(populate_database(database).casefold(), schema)
252+
for database, schema in used_schemas])
253+
251254
if (
252255
relations is None
253256
or len(relations) > 100
@@ -446,3 +449,15 @@ def submit_python_job(self, parsed_model: dict, compiled_code: str):
446449
response, _ = self.execute(sql=py_q_drop_script)
447450
logger.info(response)
448451
return response
452+
453+
def acquire_connection(self, name=None) -> Connection:
454+
connection = self.connections.set_connection_name(name)
455+
if connection.credentials.database is None or connection.credentials.database.lower() == 'none':
456+
with connection.handle.cursor() as cr:
457+
cr.execute("select SYS_CONTEXT('userenv', 'DB_NAME') FROM DUAL")
458+
r = cr.fetchone()
459+
database = r[0]
460+
logger.warning(warning_tag(yellow(MISSING_DATABASE_NAME_FOR_CATALOG_WARNING_MESSAGE.format(database))))
461+
self.config.credentials.database = database
462+
connection.credentials.database = database
463+
return connection

0 commit comments

Comments
 (0)