25. Extending python-oracledb — python-oracledb 3.2.0b1 documentation (original) (raw)

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.

25.1. Subclassing Connections

Subclassing 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 does not exist

In production applications, be careful not to log sensitive information.

See Subclassing.py for an example.

25.2. Python-oracledb Plugins

Plugins 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:

To import these python-oracledb plugins in your application, useimport 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.

25.2.1. Building Custom Plugins

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://”.

  1. In a terminal or IDE, create a working directory, for example myplugin. Inside the working directory create the subdirectory hierarchysrc/oracledb/plugins/:
    mkdir myplugin
    mkdir -p myplugin/src/oracledb/plugins
  2. 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
      [options.packages.find]
      where = src
  3. 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)

  1. Build the sample package:
    cd myplugin
    python -m pip install build
    python -m build
  2. Install the sample package:
    python -m pip install dist/myplugin-1.0.0-py3-none-any.whl
  3. To show the plugin being used, create an application file containing:
    import oracledb
    import oracledb.plugins.myplugin
    cs = 'myprefix://localhost/orclpdb1'
    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/orclpdb1
    host=localhost, port=1521, service name=orclpdb1
  4. To uninstall the plugin, simply remove the package:
    python -m pip uninstall myplugin

25.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.

25.3.1. Connection Protocol Hooks

The 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.

25.3.2. Connection Password Hooks

The 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.

25.3.3. Connection Parameter Hooks

The 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.