1
1
#!/usr/bin/env python
2
- # -*- coding: utf-8 -*--
3
2
4
- # Copyright (c) 2021, 2023 Oracle and/or its affiliates.
3
+ # Copyright (c) 2021, 2024 Oracle and/or its affiliates.
5
4
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
6
5
7
6
"""
17
16
Note: We need to account for cx_Oracle though oracledb can operate in thick mode. The end user may be is using one of the old conda packs or an environment where cx_Oracle is the only available driver.
18
17
"""
19
18
20
- from ads .common .utils import ORACLE_DEFAULT_PORT
21
-
22
19
import logging
23
- import numpy as np
24
20
import os
25
- import pandas as pd
26
21
import tempfile
27
- from time import time
28
- from typing import Dict , Optional , List , Union , Iterator
29
22
import zipfile
23
+ from time import time
24
+ from typing import Dict , Iterator , List , Optional , Union
25
+
26
+ import numpy as np
27
+ import pandas as pd
28
+
30
29
from ads .common .decorator .runtime_dependency import (
31
30
OptionalDependency ,
32
31
)
32
+ from ads .common .utils import ORACLE_DEFAULT_PORT
33
33
34
34
logger = logging .getLogger ("ads.oracle_connector" )
35
35
CX_ORACLE = "cx_Oracle"
40
40
import oracledb as oracle_driver # Both the driver share same signature for the APIs that we are using.
41
41
42
42
PYTHON_DRIVER_NAME = PYTHON_ORACLEDB
43
- except :
43
+ except ModuleNotFoundError :
44
44
logger .info ("oracledb package not found. Trying to load cx_Oracle" )
45
45
try :
46
46
import cx_Oracle as oracle_driver
47
47
48
48
PYTHON_DRIVER_NAME = CX_ORACLE
49
- except ModuleNotFoundError :
49
+ except ModuleNotFoundError as err2 :
50
50
raise ModuleNotFoundError (
51
51
f"Neither `oracledb` nor `cx_Oracle` module was not found. Please run "
52
52
f"`pip install { OptionalDependency .DATA } `."
53
- )
53
+ ) from err2
54
54
55
55
56
56
class OracleRDBMSConnection (oracle_driver .Connection ):
@@ -75,7 +75,7 @@ def __init__(
75
75
logger .info (
76
76
"Running oracledb driver in thick mode. For mTLS based connection, thick mode is default."
77
77
)
78
- except :
78
+ except Exception :
79
79
logger .info (
80
80
"Could not use thick mode. The driver is running in thin mode. System might prompt for passphrase"
81
81
)
@@ -154,7 +154,6 @@ def insert(
154
154
batch_size = 100000 ,
155
155
encoding = "utf-8" ,
156
156
):
157
-
158
157
if if_exists not in ["fail" , "replace" , "append" ]:
159
158
raise ValueError (
160
159
f"Unknown option `if_exists`={ if_exists } . Valid options are 'fail', 'replace', 'append'"
@@ -173,7 +172,6 @@ def insert(
173
172
df_orcl .columns = df_orcl .columns .str .replace (r"\W+" , "_" , regex = True )
174
173
table_exist = True
175
174
with self .cursor () as cursor :
176
-
177
175
if if_exists != "replace" :
178
176
try :
179
177
cursor .execute (f"SELECT 1 from { table_name } FETCH NEXT 1 ROWS ONLY" )
@@ -275,7 +273,6 @@ def chunks(lst: List, batch_size: int):
275
273
yield lst [i : i + batch_size ]
276
274
277
275
for batch in chunks (record_data , batch_size = batch_size ):
278
-
279
276
cursor .executemany (sql , batch , batcherrors = True )
280
277
281
278
for error in cursor .getbatcherrors ():
@@ -304,7 +301,6 @@ def _fetch_by_batch(self, cursor, chunksize):
304
301
def query (
305
302
self , sql : str , bind_variables : Optional [Dict ], chunksize = None
306
303
) -> Union [pd .DataFrame , Iterator [pd .DataFrame ]]:
307
-
308
304
start_time = time ()
309
305
310
306
cursor = self .cursor ()
@@ -315,10 +311,8 @@ def query(
315
311
cursor .execute (sql , ** bind_variables )
316
312
columns = [row [0 ] for row in cursor .description ]
317
313
df = iter (
318
- (
319
- pd .DataFrame (data = rows , columns = columns )
320
- for rows in self ._fetch_by_batch (cursor , chunksize )
321
- )
314
+ pd .DataFrame (data = rows , columns = columns )
315
+ for rows in self ._fetch_by_batch (cursor , chunksize )
322
316
)
323
317
324
318
else :
@@ -332,3 +326,21 @@ def query(
332
326
)
333
327
334
328
return df
329
+
330
+
331
+ def get_adw_connection (vault_secret_id : str ) -> "oracledb.Connection" :
332
+ """Creates ADW connection from the credentials stored in the vault"""
333
+ import oracledb
334
+
335
+ from ads .secrets .adb import ADBSecretKeeper
336
+
337
+ secret = vault_secret_id
338
+
339
+ logging .getLogger ().debug ("A secret id was used to retrieve credentials." )
340
+ creds = ADBSecretKeeper .load_secret (secret ).to_dict ()
341
+ user = creds .pop ("user_name" , None )
342
+ password = creds .pop ("password" , None )
343
+ if not user or not password :
344
+ raise ValueError (f"The user or password is missing in { secret } " )
345
+ logging .getLogger ().debug ("Downloaded secrets successfully." )
346
+ return oracledb .connect (user = user , password = password , ** creds )
0 commit comments