1818from typing import (
1919 Optional , List , Set , FrozenSet , Tuple , Iterable
2020)
21- from itertools import chain
2221from typing import (
2322 Any ,
2423 Callable ,
3130from dbt_common .contracts .constraints import ConstraintType
3231from dbt_common .utils import filter_null_values
3332
33+ from dbt .adapters .base .connections import Connection
3434from 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
3636from dbt .adapters .contracts .relation import RelationConfig
3737from dbt .adapters .events .logging import AdapterLogger
3838from dbt .adapters .sql import SQLAdapter
4545from dbt .adapters .oracle .keyword_catalog import KEYWORDS
4646from dbt .adapters .oracle .python_submissions import OracleADBSPythonJob
4747
48+ from dbt_common .ui import warning_tag , yellow
49+
4850logger = AdapterLogger ("oracle" )
4951
5052# Added 6 random hex letters (56c36b) to table_a and table_b to avoid ORA-32031.
8183LIST_RELATIONS_MACRO_NAME = 'list_relations_without_caching'
8284GET_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
8596class 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