Skip to content

Commit 2465fd8

Browse files
committed
vdk-oracle: add new config options (host,port,sid,thick_mode_lib_dir)
We are adding 3 options host,port,sid that were being originally added as part of PR #3019 The issue in the PR is that SID was incorrecctly passed as "service_name" to the underlying oracle db connect method. But it is actuall "SID" (system identifier) . Setting it correctly there works fine. I also had to add thick_mode_lib_dir since it was impossible to get thick mode working in Mac without passing it on. Testing Done: - added test_oracle_connect_execute_without_connection_string - tested in production environment against real (non local) with thick mode database with a data job which executed query and send data for ingestion successfully. Currently the automated tests do not cover the thick mode scenario due to extra setup required and this will be added later.
1 parent 01049f8 commit 2465fd8

File tree

5 files changed

+126
-11
lines changed

5 files changed

+126
-11
lines changed

projects/vdk-plugins/vdk-oracle/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ pip install vdk-oracle
2121
| oracle_password | Password used when connecting to Oracle database | super_secret_shhhh |
2222
| oracle_use_secrets | Set to True to use secrets to connect to Oracle | True |
2323
| oracle_connection_string | The Oracle connection string | localhost:1521/free |
24+
| oracle_host | The host of the Oracle database. Note: This gets overridden if oracle_connection_string is set. | localhost |
25+
| oracle_port | The port of the Oracle database. Note: This gets overridden if oracle_connection_string is set. | 1521 |
26+
| oracle_sid | The SID of the Oracle database. Note: This gets overridden if oracle_connection_string is set. | free |
27+
| oracle_service_name | The Service name of the Oracle database. Note: This gets overridden if oracle_connection_string is set. | free |
2428
| oracle_thick_mode | Python-oracledb is said to be in Thick mode when Oracle Client libraries are used. True by default. Set to False to disable Oracle Thick mode. More info: https://python-oracledb.readthedocs.io/en/latest/user_guide/appendix_b.html | True |
2529

2630
### Example

projects/vdk-plugins/vdk-oracle/src/vdk/plugin/oracle/oracle_configuration.py

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
ORACLE_PASSWORD = "ORACLE_PASSWORD"
1414
ORACLE_USE_SECRETS = "ORACLE_USE_SECRETS"
1515
ORACLE_THICK_MODE = "ORACLE_THICK_MODE"
16+
ORACLE_THICK_MODE_LIB_DIR = "ORACLE_THICK_MODE_LIB_DIR"
1617
ORACLE_CONNECTION_STRING = "ORACLE_CONNECTION_STRING"
18+
ORACLE_HOST = "ORACLE_HOST"
19+
ORACLE_PORT = "ORACLE_PORT"
20+
ORACLE_SID = "ORACLE_SID"
21+
ORACLE_SERVICE_NAME = "ORACLE_SERVICE_NAME"
1722

1823

1924
class OracleConfiguration:
@@ -29,12 +34,27 @@ def get_oracle_password(self) -> str:
2934
def get_oracle_connection_string(self) -> str:
3035
return self.__config.get_value(ORACLE_CONNECTION_STRING)
3136

37+
def get_oracle_host(self) -> str:
38+
return self.__config.get_value(ORACLE_HOST)
39+
40+
def get_oracle_port(self) -> int:
41+
return int(self.__config.get_value(ORACLE_PORT))
42+
43+
def get_oracle_sid(self) -> str:
44+
return self.__config.get_value(ORACLE_SID)
45+
46+
def get_oracle_service_name(self) -> str:
47+
return self.__config.get_value(ORACLE_SERVICE_NAME)
48+
3249
def oracle_use_secrets(self) -> bool:
3350
return self.__config.get_value(ORACLE_USE_SECRETS)
3451

3552
def oracle_thick_mode(self) -> bool:
3653
return self.__config.get_value(ORACLE_THICK_MODE)
3754

55+
def oracle_thick_mode_lib_dir(self) -> Optional[str]:
56+
return self.__config.get_value(ORACLE_THICK_MODE_LIB_DIR)
57+
3858
@staticmethod
3959
def add_definitions(config_builder: ConfigurationBuilder):
4060
config_builder.add(
@@ -55,6 +75,30 @@ def add_definitions(config_builder: ConfigurationBuilder):
5575
is_sensitive=True,
5676
description="The Oracle database connection string",
5777
)
78+
config_builder.add(
79+
key=ORACLE_HOST,
80+
default_value=None,
81+
is_sensitive=True,
82+
description="The host of the Oracle database. Note: This option is overridden by ORACLE_CONNECTION_STRING ",
83+
)
84+
config_builder.add(
85+
key=ORACLE_PORT,
86+
default_value=1521,
87+
is_sensitive=True,
88+
description="The port of the Oracle database. Note: This option is overridden by ORACLE_CONNECTION_STRING",
89+
)
90+
config_builder.add(
91+
key=ORACLE_SID,
92+
default_value=None,
93+
is_sensitive=True,
94+
description="The schema id of the Oracle database. Note: This option is overridden by ORACLE_CONNECTION_STRING",
95+
)
96+
config_builder.add(
97+
key=ORACLE_SERVICE_NAME,
98+
default_value=None,
99+
is_sensitive=True,
100+
description="The service name of the Oracle database. Note: This option is overridden by ORACLE_CONNECTION_STRING",
101+
)
58102
config_builder.add(
59103
key=ORACLE_USE_SECRETS,
60104
default_value=True,
@@ -63,7 +107,18 @@ def add_definitions(config_builder: ConfigurationBuilder):
63107
)
64108
config_builder.add(
65109
key=ORACLE_THICK_MODE,
66-
default_value=True,
67-
description="Use oracle thick mode. Set to False to disable oracle thick mode. "
110+
default_value=False,
111+
description="Use oracle thick mode. Set to False to disable oracle thick mode."
112+
"If set to true you may need to manually install client library. "
113+
"Refer to "
114+
"https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html#enablingthick "
68115
"More info: https://python-oracledb.readthedocs.io/en/latest/user_guide/appendix_b.html",
69116
)
117+
config_builder.add(
118+
key=ORACLE_THICK_MODE_LIB_DIR,
119+
default_value=None,
120+
description="This is the location of the Oracle Client library used when thick mode is enabled. "
121+
"This option is ignored if ORACLE_THICK_MODE is false."
122+
"Before setting this follow instruction in "
123+
"https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html#enablingthick ",
124+
)

projects/vdk-plugins/vdk-oracle/src/vdk/plugin/oracle/oracle_connection.py

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import logging
44
from typing import Any
55
from typing import List
6+
from typing import Optional
67

8+
from oracledb import Connection
79
from vdk.internal.builtin_plugins.connection.managed_connection_base import (
810
ManagedConnectionBase,
911
)
@@ -14,24 +16,55 @@
1416

1517
class OracleConnection(ManagedConnectionBase):
1618
def __init__(
17-
self, user: str, password: str, connection_string: str, thick_mode: bool = True
19+
self,
20+
user: str,
21+
password: str,
22+
connection_string: str = None,
23+
host=None,
24+
port=1521,
25+
sid: str = None,
26+
service_name: str = None,
27+
thick_mode: bool = True,
28+
thick_mode_lib_dir: Optional[str] = None,
1829
):
1930
super().__init__(log)
2031
self._oracle_user = user
2132
self._oracle_password = password
33+
self._host = host
34+
self._port = port
35+
self._sid = sid
36+
self._service_name = service_name
2237
self._oracle_connection_string = connection_string
2338
self._thick_mode = thick_mode
39+
self._thick_mode_lib_dir = thick_mode_lib_dir
2440

25-
def _connect(self) -> PEP249Connection:
41+
def _connect(self) -> Connection:
2642
import oracledb
2743

2844
if self._thick_mode:
29-
oracledb.init_oracle_client()
30-
conn = oracledb.connect(
31-
user=self._oracle_user,
32-
password=self._oracle_password,
33-
dsn=self._oracle_connection_string,
34-
)
45+
if self._thick_mode_lib_dir:
46+
oracledb.init_oracle_client(self._thick_mode_lib_dir)
47+
else:
48+
oracledb.init_oracle_client()
49+
if self._oracle_connection_string:
50+
log.debug("Connecting to Oracle using connection string")
51+
params = oracledb.ConnectParams()
52+
params.set(user=self._oracle_user)
53+
params.set(password=self._oracle_password)
54+
params.parse_connect_string(self._oracle_connection_string)
55+
56+
conn = oracledb.connect(params=params)
57+
else:
58+
log.debug("Connecting to Oracle using host,port,sid")
59+
params = oracledb.ConnectParams(
60+
user=self._oracle_user,
61+
password=self._oracle_password,
62+
host=self._host,
63+
port=self._port,
64+
sid=self._sid,
65+
service_name=self._service_name,
66+
)
67+
conn = oracledb.connect(params=params)
3568
return conn
3669

3770
def _is_connected(self) -> bool:

projects/vdk-plugins/vdk-oracle/src/vdk/plugin/oracle/oracle_plugin.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ def initialize_job(self, context: JobContext):
4646
oracle_user,
4747
oracle_pass,
4848
conf.get_oracle_connection_string(),
49-
conf.oracle_thick_mode(),
49+
host=conf.get_oracle_host(),
50+
port=conf.get_oracle_port(),
51+
sid=conf.get_oracle_sid(),
52+
service_name=conf.get_oracle_service_name(),
53+
thick_mode=conf.oracle_thick_mode(),
54+
thick_mode_lib_dir=conf.oracle_thick_mode_lib_dir(),
5055
),
5156
)
5257
context.ingester.add_ingester_factory_method(

projects/vdk-plugins/vdk-oracle/tests/test_plugin.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
ORACLE_THICK_MODE = "ORACLE_THICK_MODE"
1919
VDK_LOG_EXECUTION_RESULT = "VDK_LOG_EXECUTION_RESULT"
2020
VDK_INGEST_METHOD_DEFAULT = "VDK_INGEST_METHOD_DEFAULT"
21+
ORACLE_HOST = "ORACLE_HOST"
22+
ORACLE_PORT = "ORACLE_PORT"
23+
ORACLE_SID = "ORACLE_SID"
2124

2225

2326
@pytest.mark.usefixtures("oracle_db")
@@ -27,6 +30,9 @@
2730
DB_DEFAULT_TYPE: "oracle",
2831
ORACLE_USER: "SYSTEM",
2932
ORACLE_PASSWORD: "Gr0mh3llscr3am",
33+
ORACLE_HOST: "localhost",
34+
ORACLE_PORT: "1521",
35+
ORACLE_SID: "FREE",
3036
ORACLE_CONNECTION_STRING: "localhost:1521/FREE",
3137
ORACLE_THICK_MODE: "False",
3238
VDK_LOG_EXECUTION_RESULT: "True",
@@ -42,6 +48,18 @@ def test_oracle_connect_execute(self):
4248
cli_assert_equal(0, result)
4349
_verify_query_execution(runner)
4450

51+
def test_oracle_connect_execute_without_connection_string():
52+
backup_conn_string = os.environ["ORACLE_CONNECTION_STRING"]
53+
del os.environ["ORACLE_CONNECTION_STRING"]
54+
runner = CliEntryBasedTestRunner(oracle_plugin)
55+
result: Result = runner.invoke(
56+
["run", jobs_path_from_caller_directory("oracle-connect-execute-job")]
57+
)
58+
cli_assert_equal(0, result)
59+
60+
os.environ["ORACLE_CONNECTION_STRING"] = backup_conn_string
61+
_verify_query_execution(runner)
62+
4563
def test_oracle_ingest_existing_table(self):
4664
runner = CliEntryBasedTestRunner(oracle_plugin)
4765
result: Result = runner.invoke(

0 commit comments

Comments
 (0)