_dbi_base - Private base module for all database interfaces

Purpose:

This module contains the library's base database methods and attribute accessors, which are designed to be specialised by the database-specific modules and classes.

Platform:

Linux/Windows | Python 3.10+

Developer:

J Berendt

Email:

support@s3dev.uk

Comments:

This module contains only methods which can safely be inherited and used by any of its subclasses.

In other words, this module should not contain any import statement, or uses of these imports, which if used in a database-specific module will cause a crash due to a missing library.

Any database-specific functionality must be contained in that module.

Example:

For class-specific usage examples, please refer to the docstring for the following classes:

exception _dbi_base.SecurityWarning[source]

Bases: Warning

Security warning stub-class.

__cause__

exception cause

__context__

exception context

__delattr__(name, /)

Implement delattr(self, name).

__getattribute__(name, /)

Return getattr(self, name).

__init__(*args, **kwargs)
__new__(**kwargs)
__reduce__()

Helper for pickle.

__repr__()

Return repr(self).

__setattr__(name, value, /)

Implement setattr(self, name, value).

__setstate__()
__str__()

Return str(self).

__suppress_context__
__traceback__
add_note()

Exception.add_note(note) -- add a note to the exception

args
with_traceback()

Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.

class _dbi_base._DBIBase(connstr: str)[source]

Bases: object

This class holds the methods and properties which are used across all databases. Each of the database-specific constructors inherits this class for its members.

Note

This class is not designed to be interacted with directly.

Rather, please use the database.DBInterface class instead, as the proper interface class has an automatic switch for database interfaces, based on the sqlalchemy.Engine object which is created from the connection string.

Parameters:

connstr (str) -- The database-specific SQLAlchemy connection string.

Example Use:

This low-level generalised class is designed to be inherited by the calling/wrapping class as:

>>> from dblib.database import DBInterface

class MyDB(DBInterface):

    def __init__(self, connstr: str):
        super().__init__(connstr=('mysql+mysqlconnector://'
                                  '<user>:<pwd>@<host>:<port>/'
                                  '<db_name>'))
_PREFIX = '\n[DatabaseError]:'
__init__(connstr: str)[source]

Class initialiser.

_create_engine() sqlalchemy.engine.base.Engine[source]

Create a database engine using the provided environment.

Returns:

A sqlalchemy database engine object.

Return type:

sqlalchemy.engine.base.Engine

static _is_dangerous(stmt: str) bool[source]

Perform a dirty security check for injection attempts.

Parameters:

stmt (str) -- SQL statement to be potentially executed.

Raises:

SecurityWarning -- If there are multiple semi-colons (;) in the statement, or any comment delimiters (--).

Returns:

False if the checks pass.

Return type:

bool

_report_sa_error(msg: str, error: sqlalchemy.exc.SQLAlchemyError)[source]

Report SQLAlchemy error to the terminal.

Parameters:
  • msg (str) -- Additional error to be displayed. This message will be automatically prefixed with '[DatabaseError]: '

  • error (sqlalchemy.exc.SQLAlchemyError) -- Caught error object from the try/except block.

static _result_to_df__cursor(result: sqlalchemy.engine.cursor.CursorResult) DataFrame[source]

Convert a CursorResult object to a DataFrame.

If the cursor did not return results, an empty DataFrame containing the column names only, is returned.

Parameters:

result (sqlalchemy.engine.cursor.CursorResult) -- Object to be converted.

Returns:

A pandas.DataFrame object containing the cursor's data.

Return type:

pd.DataFrame

static _result_to_df__stored(result: object) DataFrame[source]

Convert a MySQLCursor.stored_results object to a DataFrame.

Parameters:
  • result (object) -- The cursor.stored_results() object from

  • call. (a sqlalchemy or mysql.connector procedure)

Returns:

A DataFrame containing the results from the procedure call.

Return type:

pd.DataFrame

property database_name

Accessor to the database name used by the engine object.

property engine

Accessor to the sqlalchemy.engine.base.Engine object.

execute_query(stmt: str, params: dict = None, raw: bool = True) list | DataFrame | None[source]

Execute a query statement.

Important

The following are not allowed to be executed by this method:

  • Statements containing multiple semi-colons (;).

  • Statements containing a comment delimiter (--).

If found, a SecurityWarning will be raised by the _is_dangerous() method.

Parameters:
  • stmt (str) -- Statement to be executed. The parameter bindings are to be written in colon format.

  • params (dict, optional) -- Parameter key/value bindings as a dictionary, if applicable. Defaults to None.

  • raw (bool, optional) -- Return the data in 'raw' (tuple) format rather than as a formatted DataFrame. Defaults to True for efficiency.

If the query did not return results and the raw argument is False, an empty DataFrame containing the column names only, is returned.

Note

In the SQL query, the bind parameters are specified by name, using the format :bind_name. The params dictionary argument must contain the associated parameter name/value bindings.

Warning

  1. Generally, whatever statement is passed into this method will be executed, and may have destructive implications.

  2. This method contains a commit call.

If a statement is passed into this method, and the user has the appropriate permissions - the change will be committed.

... HC SVNT DRACONES.

Returns:

If the raw parameter is True, a list of tuples containing values is returned. Otherwise, a pandas.DataFrame object containing the returned data is returned.

If this method is called with a script which does not return results, for example a CREATE script, None is returned; regardless of the value passed to the raw parameter.

Return type:

list | pd.DataFrame | None