You can extend the capabilities of python-oracledb by using standard Python functionality for subclassing python-oracledb classes. You can also use python-oracledb plugins, connection protocol hooks, connection password hooks, and connection parameter hooks.
26.1. Subclassing ConnectionsSubclassing enables applications to change python-oracledb, for example by extending connection and statement execution behavior. This can be used to alter, or log, connection and execution parameters, or to further change python-oracledb functionality.
The example below demonstrates subclassing a connection to log SQL execution to a file. This example also shows how connection credentials can be embedded in the custom subclass, so application code does not need to supply them.
class Connection(oracledb.Connection): log_file_name = "log.txt" def __init__(self): connect_string = "hr/hr_password@dbhost.example.com/orclpdb" self._log("Connect to the database") return super(Connection, self).__init__(connect_string) def _log(self, message): with open(self.log_file_name, "a") as f: print(message, file=f) def execute(self, sql, parameters): self._log(sql) cursor = self.cursor() try: return cursor.execute(sql, parameters) except oracledb.Error as e: error_obj, = e.args self._log(error_obj.message) raise connection = Connection() connection.execute(""" select department_name from departments where department_id = :id""", dict(id=270))
The messages logged in log.txt
are:
Connect to the database select department_name from departments where department_id = :id
If an error occurs, perhaps due to a missing table, the log file would contain instead:
Connect to the database select department_name from departments where department_id = :id ORA-00942: table or view "HR"."DEPARTMENTS" does not exist
In production applications, be careful not to log sensitive information.
See Subclassing.py for an example.
26.2. Python-oracledb PluginsPlugins simplify extending python-oracledb functionality, and optionally allow the distribution of such extensions as modules. The plugin mechanism provides a loose coupling for python-oracledb, permitting different python-oracledb configurations.
Examples are the pre-supplied plugins for Centralized Configuration Providers. The loose coupling allows these plugins to be included with all python-oracledb installations but the large Python SDK modules used by the plugins are not installed as python-oracledb dependencies. Only users who want to use a specific configuration provider plugin need to install its required SDK.
All python-oracledb installations bundle the following plugins:
oci_config_provider
which allows connection and pool creation calls to access connection configuration information stored in OCI Object Storage. See Using an OCI Object Storage Centralized Configuration Provider.
azure_config_provider
which allows connection and pool creation calls to access connection configuration information stored using Azure App Configuration. See Using an Azure App Centralized Configuration Provider.
oci_tokens
which uses the Oracle Cloud Infrastructure (OCI) Software Development Kit (SDK) to generate access tokens when authenticating with OCI Identity and Access Management (IAM) token-based authentication. See OCI Cloud Native Authentication with the oci_tokens Plugin.
azure_tokens
which uses the Microsoft Authentication Library (MSAL) to generate access tokens when authenticating with OAuth 2.0 token-based authentication. See Azure Cloud Native Authentication with the azure_tokens Plugin.
To import these python-oracledb plugins in your application, use import oracledb.plugins.<name of plugin>
, for example:
import oracledb.plugins.oci_tokens
Note that the namespace oracledb.plugins.ldap_support
is reserved for future use by the python-oracledb project.
If you want to use the plugin mechanism for your own packages, you can create a namespace package. You can distribute plugin packages either internally within your organization, or on a package repository such as PyPI.
The following example creates a plugin that uses a connection protocol hook function to do special processing of connection strings prefixed with “myprefix://”.
In a terminal or IDE, create a working directory, for example myplugin
. Inside the working directory create the subdirectory hierarchy src/oracledb/plugins/
:
mkdir myplugin mkdir -p myplugin/src/oracledb/plugins
In the myplugin
directory, create the following files:
A README
file:
My sample connection plugin.
A pyproject.toml
file:
[build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta"
A setup.cfg
file:
[metadata] name = myplugin version = 1.0.0 description = Sample connection plugin for python-oracleb long_description = file: README long_description_content_type = text/markdown author = Your Name author_email = youremail@example.com license = Apache Software License [options] zip_safe = False package_dir = =src install_requires = oracledb [options.packages.find] where = src
Create the plugin code in myplugin/src/oracledb/plugins/myplugin.py
:
import oracledb def myhookfunc(protocol, arg, params): print(f"In myhookfunc: protocol={protocol} arg={arg}") params.parse_connect_string(arg) oracledb.register_protocol("myprefix", myhookfunc)
Build the sample package:
cd myplugin python -m pip install build python -m build
Install the sample package:
python -m pip install dist/myplugin-1.0.0-py3-none-any.whl
To show the plugin being used, create an application file containing:
import oracledb import oracledb.plugins.myplugin cs = "myprefix://localhost/orclpdb" cp = oracledb.ConnectParams() cp.parse_connect_string(cs) print(f"host={cp.host}, port={cp.port}, service name={cp.service_name}")
Running this will print:
In myhookfunc: protocol=myprefix arg=localhost/orclpdb host=localhost, port=1521, service name=orclpdb
To uninstall the plugin, simply remove the package:
python -m pip uninstall myplugin
Another sample plugin shows how all connection creations can be logged, regardless of the connection string. If the plugin myplugin/src/oracledb/plugins/myplugin.py
registers a connection parameter hook:
import oracledb def my_params_hook(params: oracledb.ConnectParams): print(f"Connecting to the database as {params.user}") oracledb.register_params_hook(my_params_hook)
Then running an application that contains:
connection = oracledb.connect(user="hr", password=userpwd, dsn="dbhost.example.com/orclpdb")
will print the trace output:
Connecting to the database as hr26.3. Connection Hooks
Connection hooks allow you to modify the connection logic based on your needs. The hooks supported by python-oracledb are listed in this section.
26.3.1. Connection Protocol HooksThe oracledb.register_protocol()
method registers a user protocol hook function that can be called internally by python-oracledb prior to connection or pool creation.
See Using Protocol Hook Functions for usage information.
26.3.2. Connection Password HooksThe oracledb.register_password_type()
method registers a user password hook function that will be called internally by python-oracledb prior to connection or pool creation.
See Using Password Hook Functions for usage information.
26.3.3. Connection Parameter HooksThe oracledb.register_params_hook()
method registers a user parameter hook function that will be called internally by python-oracledb prior to connection or pool creation.
See Using Parameter Hook Functions for usage information.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4