_dbi_mysql - Private database interface for MySQL and MariaDB — dbilib - v0.4.0rc1 Documentation

# _dbi_mysql - Private database interface for MySQL and MariaDB

Purpose:

  This module contains the library's MySQL database methods and attribute accessors; which are a specialised version of the `_dbi_base._DBIBase` class methods.

Platform:

  Linux/Windows | Python 3.10+

Developer:

  J Berendt

Email:

  support@s3dev.uk

Comments:

  n/a

Example:

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

  > - `_DBIMySQL`

class _dbi_mysql._DBIMySQL(connstr: str)

  Bases: `_DBIBase`

  This private class holds the methods and properties which are used for accessing MySQL-like databases, including MariaDB.

  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 dbilib.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]:'
  __annotations__ = {}
  __init__(connstr: str)

    Class initialiser.

  _create_engine() → sqlalchemy.engine.base.Engine

    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

    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)

    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

    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

    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

  call_procedure(proc: str, params: list | tuple = None, return_status: bool = False) → DataFrame | tuple[DataFrame | bool]

    Call a stored procedure, and return as a DataFrame.

    Parameters:

      - proc (str) -- Name of the stored procedure to call.

      - params (list | tuple, optional) -- A list (or tuple) of parameters to pass into the procedure. Defaults to None.

      - return_status (bool, optional) -- Return the method's success status. Defaults to False.

    Returns:

      If the `return_status` argument is True, a tuple of the data and the method's return status is returned as:

          (df, status)

      Otherwise, only the data is returned, as a pd.DataFrame.

    Return type:

      pd.DataFrame | tuple[pd.DataFrame | bool]

  call_procedure_update(proc: str, params: list = None, return_id: bool = False) → bool | tuple

    Call an update or insert stored procedure.

    Note

    Results are not returned from this call, only a boolean status flag and the optional last row ID.

    If results are desired, please use the :meth:~`call_procedure` method.

    Parameters:

      - proc (str) -- Name of the stored procedure to call.

      - params (list, optional) -- A list of parameters to pass into the USP. Defaults to None.

      - return_id (bool, optional) -- Return the ID of the last inserted row. Defaults to False.

    Returns:

      If `return_id` is False, True is returned if the procedure completed successfully, otherwise False. If `return_id` is True, a tuple containing the ID of the last inserted row and the execution success flag are returned as:

          (id, success_flag)

    Return type:

      bool | tuple

  call_procedure_update_many(*args, proc: str, iterable: list | tuple) → bool

    Call an update or insert stored procedure for an iterable.

    Note

    The arguments are passed into the USP in the following order:

    > *args, iterable_item

    Ensure the USP is designed to accept the iterable item as the last parameter.

    Parameters:

      - *args (Union[str, int, float]) -- Positional arguments to be passed into the USP, in front of each iterable item. Note: The parameters are passed into the USP in the order received, followed by the iterable item.

      - proc (str) -- Name of the stored procedure to call.

      - iterable (list | tuple) -- List of items to be loaded into the database.

    Returns:

      True if the update was successful, otherwise False.

    Return type:

      bool

  call_procedure_update_raw(proc: str, params: list = None)

    Call an update or insert stored procedure, without error handling.

    Warning

    This method is unprotected, perhaps use `call_procedure_update()` instead.

    This 'raw' method does not contain an error handler. It is (by design) the responsibility of the caller to contain and control the errors.

    The purpose of this raw method is to enable the caller method to contain and control the errors which might be generated from a USP call, for example a duplicate key error.

    Parameters:

      - proc (str) -- Name of the stored procedure to call.

      - params (list, optional) -- A list of parameters to pass into the USP. Defaults to None.

  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

    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

  table_exists(table_name: str, verbose: bool = False) → bool

    Using the `engine` object, test if the given table exists.

    Parameters:

      - table_name (str) -- Name of the table to test.

      - verbose (bool, optional) -- Print a message if the table does not exist. Defaults to False.

    Returns:

      True if the given table exists, otherwise False.

    Return type:

      bool