Skip to content

Commit 2a084ee

Browse files
authored
Update Oracle library to latest version (#24311)
1 parent 7d8a17b commit 2a084ee

File tree

11 files changed

+69
-119
lines changed

11 files changed

+69
-119
lines changed

β€Žairflow/providers/google/cloud/transfers/oracle_to_gcs.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from decimal import Decimal
2323
from typing import Dict
2424

25-
import cx_Oracle
25+
import oracledb
2626

2727
from airflow.providers.google.cloud.transfers.sql_to_gcs import BaseSQLToGCSOperator
2828
from airflow.providers.oracle.hooks.oracle import OracleHook
@@ -45,15 +45,15 @@ class OracleToGCSOperator(BaseSQLToGCSOperator):
4545
ui_color = '#a0e08c'
4646

4747
type_map = {
48-
cx_Oracle.DB_TYPE_BINARY_DOUBLE: 'DECIMAL',
49-
cx_Oracle.DB_TYPE_BINARY_FLOAT: 'DECIMAL',
50-
cx_Oracle.DB_TYPE_BINARY_INTEGER: 'INTEGER',
51-
cx_Oracle.DB_TYPE_BOOLEAN: 'BOOLEAN',
52-
cx_Oracle.DB_TYPE_DATE: 'TIMESTAMP',
53-
cx_Oracle.DB_TYPE_NUMBER: 'NUMERIC',
54-
cx_Oracle.DB_TYPE_TIMESTAMP: 'TIMESTAMP',
55-
cx_Oracle.DB_TYPE_TIMESTAMP_LTZ: 'TIMESTAMP',
56-
cx_Oracle.DB_TYPE_TIMESTAMP_TZ: 'TIMESTAMP',
48+
oracledb.DB_TYPE_BINARY_DOUBLE: 'DECIMAL', # type: ignore
49+
oracledb.DB_TYPE_BINARY_FLOAT: 'DECIMAL', # type: ignore
50+
oracledb.DB_TYPE_BINARY_INTEGER: 'INTEGER', # type: ignore
51+
oracledb.DB_TYPE_BOOLEAN: 'BOOLEAN', # type: ignore
52+
oracledb.DB_TYPE_DATE: 'TIMESTAMP', # type: ignore
53+
oracledb.DB_TYPE_NUMBER: 'NUMERIC', # type: ignore
54+
oracledb.DB_TYPE_TIMESTAMP: 'TIMESTAMP', # type: ignore
55+
oracledb.DB_TYPE_TIMESTAMP_LTZ: 'TIMESTAMP', # type: ignore
56+
oracledb.DB_TYPE_TIMESTAMP_TZ: 'TIMESTAMP', # type: ignore
5757
}
5858

5959
def __init__(self, *, oracle_conn_id='oracle_default', ensure_utc=False, **kwargs):

β€Žairflow/providers/oracle/hooks/oracle.py

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from datetime import datetime
2222
from typing import Dict, List, Optional, Union
2323

24-
import cx_Oracle
24+
import oracledb
2525

2626
try:
2727
import numpy
@@ -57,7 +57,7 @@ class OracleHook(DbApiHook):
5757

5858
supports_autocommit = True
5959

60-
def get_conn(self) -> 'OracleHook':
60+
def get_conn(self) -> oracledb.Connection:
6161
"""
6262
Returns a oracle connection object
6363
Optional parameters for using a custom DSN connection
@@ -84,8 +84,8 @@ def get_conn(self) -> 'OracleHook':
8484
)
8585
}
8686
87-
see more param detail in
88-
`cx_Oracle.connect <https://cx-oracle.readthedocs.io/en/latest/module.html#cx_Oracle.connect>`_
87+
see more param detail in `oracledb.connect
88+
<https://python-oracledb.readthedocs.io/en/latest/api_manual/module.html#oracledb.connect>`_
8989
9090
9191
"""
@@ -98,9 +98,9 @@ def get_conn(self) -> 'OracleHook':
9898
service_name = conn.extra_dejson.get('service_name')
9999
port = conn.port if conn.port else 1521
100100
if conn.host and sid and not service_name:
101-
conn_config['dsn'] = cx_Oracle.makedsn(conn.host, port, sid)
101+
conn_config['dsn'] = oracledb.makedsn(conn.host, port, sid)
102102
elif conn.host and service_name and not sid:
103-
conn_config['dsn'] = cx_Oracle.makedsn(conn.host, port, service_name=service_name)
103+
conn_config['dsn'] = oracledb.makedsn(conn.host, port, service_name=service_name)
104104
else:
105105
dsn = conn.extra_dejson.get('dsn')
106106
if dsn is None:
@@ -119,51 +119,40 @@ def get_conn(self) -> 'OracleHook':
119119
dsn += "/" + conn.schema
120120
conn_config['dsn'] = dsn
121121

122-
if 'encoding' in conn.extra_dejson:
123-
conn_config['encoding'] = conn.extra_dejson.get('encoding')
124-
# if `encoding` is specific but `nencoding` is not
125-
# `nencoding` should use same values as `encoding` to set encoding, inspired by
126-
# https://github.com/oracle/python-cx_Oracle/issues/157#issuecomment-371877993
127-
if 'nencoding' not in conn.extra_dejson:
128-
conn_config['nencoding'] = conn.extra_dejson.get('encoding')
129-
if 'nencoding' in conn.extra_dejson:
130-
conn_config['nencoding'] = conn.extra_dejson.get('nencoding')
131-
if 'threaded' in conn.extra_dejson:
132-
conn_config['threaded'] = conn.extra_dejson.get('threaded')
133122
if 'events' in conn.extra_dejson:
134123
conn_config['events'] = conn.extra_dejson.get('events')
135124

136125
mode = conn.extra_dejson.get('mode', '').lower()
137126
if mode == 'sysdba':
138-
conn_config['mode'] = cx_Oracle.SYSDBA
127+
conn_config['mode'] = oracledb.AUTH_MODE_SYSDBA
139128
elif mode == 'sysasm':
140-
conn_config['mode'] = cx_Oracle.SYSASM
129+
conn_config['mode'] = oracledb.AUTH_MODE_SYSASM
141130
elif mode == 'sysoper':
142-
conn_config['mode'] = cx_Oracle.SYSOPER
131+
conn_config['mode'] = oracledb.AUTH_MODE_SYSOPER
143132
elif mode == 'sysbkp':
144-
conn_config['mode'] = cx_Oracle.SYSBKP
133+
conn_config['mode'] = oracledb.AUTH_MODE_SYSBKP
145134
elif mode == 'sysdgd':
146-
conn_config['mode'] = cx_Oracle.SYSDGD
135+
conn_config['mode'] = oracledb.AUTH_MODE_SYSDGD
147136
elif mode == 'syskmt':
148-
conn_config['mode'] = cx_Oracle.SYSKMT
137+
conn_config['mode'] = oracledb.AUTH_MODE_SYSKMT
149138
elif mode == 'sysrac':
150-
conn_config['mode'] = cx_Oracle.SYSRAC
139+
conn_config['mode'] = oracledb.AUTH_MODE_SYSRAC
151140

152141
purity = conn.extra_dejson.get('purity', '').lower()
153142
if purity == 'new':
154-
conn_config['purity'] = cx_Oracle.ATTR_PURITY_NEW
143+
conn_config['purity'] = oracledb.PURITY_NEW
155144
elif purity == 'self':
156-
conn_config['purity'] = cx_Oracle.ATTR_PURITY_SELF
145+
conn_config['purity'] = oracledb.PURITY_SELF
157146
elif purity == 'default':
158-
conn_config['purity'] = cx_Oracle.ATTR_PURITY_DEFAULT
147+
conn_config['purity'] = oracledb.PURITY_DEFAULT
159148

160-
conn = cx_Oracle.connect(**conn_config)
149+
conn = oracledb.connect(**conn_config)
161150
if mod is not None:
162151
conn.module = mod
163152

164153
# if Connection.schema is defined, set schema after connecting successfully
165154
# cannot be part of conn_config
166-
# https://cx-oracle.readthedocs.io/en/latest/api_manual/connection.html?highlight=schema#Connection.current_schema
155+
# https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html?highlight=schema#Connection.current_schema
167156
# Only set schema when not using conn.schema as Service Name
168157
if schema and service_name:
169158
conn.current_schema = schema
@@ -184,7 +173,7 @@ def insert_rows(
184173
the whole set of inserts is treated as one transaction
185174
Changes from standard DbApiHook implementation:
186175
187-
- Oracle SQL queries in cx_Oracle can not be terminated with a semicolon (`;`)
176+
- Oracle SQL queries in oracledb can not be terminated with a semicolon (`;`)
188177
- Replace NaN values with NULL using `numpy.nan_to_num` (not using
189178
`is_nan()` because of input types error for strings)
190179
- Coerce datetime cells to Oracle DATETIME format during insert
@@ -245,7 +234,7 @@ def bulk_insert_rows(
245234
commit_every: int = 5000,
246235
):
247236
"""
248-
A performant bulk insert for cx_Oracle
237+
A performant bulk insert for oracledb
249238
that uses prepared statements via `executemany()`.
250239
For best performance, pass in `rows` as an iterator.
251240
@@ -307,7 +296,7 @@ def callproc(
307296
provided `parameters` argument.
308297
309298
See
310-
https://cx-oracle.readthedocs.io/en/latest/api_manual/cursor.html#Cursor.var
299+
https://python-oracledb.readthedocs.io/en/latest/api_manual/cursor.html#Cursor.var
311300
for further reference.
312301
"""
313302
if parameters is None:

β€Ždocs/apache-airflow-providers-google/operators/transfer/oracle_to_gcs.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@ Reference
4949
---------
5050

5151
For further information, look at:
52-
* `cx_Oracle Documentation <https://cx-oracle.readthedocs.io/en/latest/>`__
52+
* `oracledb Documentation <https://python-oracledb.readthedocs.io/en/latest/>`__
5353
* `Google Cloud Storage Documentation <https://cloud.google.com/storage/>`__

β€Ždocs/apache-airflow-providers-oracle/connections/oracle.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ Extra (optional)
8282
Schema = "orcl"
8383
8484
85-
More details on all Oracle connect parameters supported can be found in `cx_Oracle documentation
86-
<https://cx-oracle.readthedocs.io/en/latest/api_manual/module.html#cx_Oracle.connect>`_.
85+
More details on all Oracle connect parameters supported can be found in `oracledb documentation
86+
<https://python-oracledb.readthedocs.io/en/latest/api_manual/module.html#oracledb.connect>`_.
8787

8888
Information on creating an Oracle Connection through the web user interface can be found in Airflow's :doc:`Managing Connections Documentation <apache-airflow:howto/connection>`.
8989

β€Ždocs/apache-airflow-providers-oracle/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Requirements
7979
PIP package Version required
8080
================== ==================
8181
``apache-airflow`` ``>=2.2.0``
82-
``cx_Oracle`` ``>=5.1.2``
82+
``oracledb`` ``>=1.0.0``
8383
================== ==================
8484

8585
.. include:: ../../airflow/providers/oracle/CHANGELOG.rst

β€Ždocs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,6 @@ def _get_params(root_schema: dict, prefix: str = "", default_section: str = "")
551551
'celery',
552552
'cloudant',
553553
'cryptography',
554-
'cx_Oracle',
555554
'datadog',
556555
'distributed',
557556
'docker',
@@ -567,6 +566,7 @@ def _get_params(root_schema: dict, prefix: str = "", default_section: str = "")
567566
'kubernetes',
568567
'msrestazure',
569568
'oss2',
569+
'oracledb',
570570
'pandas',
571571
'pandas_gbq',
572572
'paramiko',

β€Žsetup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ def write_version(filename: str = os.path.join(*[my_dir, "airflow", "git_version
463463
'opsgenie-sdk>=2.1.5',
464464
]
465465
oracle = [
466-
'cx_Oracle>=5.1.2',
466+
'oracledb>=1.0.0',
467467
]
468468
pagerduty = [
469469
'pdpyras>=4.1.2',

β€Žtests/providers/google/cloud/transfers/test_oracle_to_gcs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import unittest
2020
from unittest import mock
2121

22-
import cx_Oracle
22+
import oracledb
2323

2424
from airflow.providers.google.cloud.transfers.oracle_to_gcs import OracleToGCSOperator
2525

@@ -32,8 +32,8 @@
3232

3333
ROWS = [('mock_row_content_1', 42), ('mock_row_content_2', 43), ('mock_row_content_3', 44)]
3434
CURSOR_DESCRIPTION = (
35-
('some_str', cx_Oracle.DB_TYPE_VARCHAR, None, None, None, None, None),
36-
('some_num', cx_Oracle.DB_TYPE_NUMBER, None, None, None, None, None),
35+
('some_str', oracledb.DB_TYPE_VARCHAR, None, None, None, None, None), # type: ignore
36+
('some_num', oracledb.DB_TYPE_NUMBER, None, None, None, None, None), # type: ignore
3737
)
3838
NDJSON_LINES = [
3939
b'{"some_num": 42, "some_str": "mock_row_content_1"}\n',

β€Žtests/providers/microsoft/azure/transfers/test_oracle_to_azure_data_lake.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ def test_write_temp_file(self):
4444
delimiter = '|'
4545
encoding = 'utf-8'
4646
cursor_description = [
47-
('id', "<class 'cx_Oracle.NUMBER'>", 39, None, 38, 0, 0),
48-
('description', "<class 'cx_Oracle.STRING'>", 60, 240, None, None, 1),
47+
('id', "<class 'oracledb.NUMBER'>", 39, None, 38, 0, 0),
48+
('description', "<class 'oracledb.STRING'>", 60, 240, None, None, 1),
4949
]
5050
cursor_rows = [[1, 'description 1'], [2, 'description 2']]
5151
mock_cursor = MagicMock()
@@ -95,8 +95,8 @@ def test_execute(self, mock_data_lake_hook, mock_oracle_hook):
9595
delimiter = '|'
9696
encoding = 'latin-1'
9797
cursor_description = [
98-
('id', "<class 'cx_Oracle.NUMBER'>", 39, None, 38, 0, 0),
99-
('description', "<class 'cx_Oracle.STRING'>", 60, 240, None, None, 1),
98+
('id', "<class 'oracledb.NUMBER'>", 39, None, 38, 0, 0),
99+
('description', "<class 'oracledb.STRING'>", 60, 240, None, None, 1),
100100
]
101101
cursor_rows = [[1, 'description 1'], [2, 'description 2']]
102102
cursor_mock = MagicMock()

0 commit comments

Comments
 (0)