database - Public database interface
The database interface class database.DBInterface
requires a valid
connection string (or database URL) on instantiation. For convenience,
the connection string templates and associated documentation can be
found in the Using the Library --> Connection Strings
section of this documentation.
- Purpose:
This module provides the library's primary entry-point for accessing the database methods and attributes.
- Platform:
Linux/Windows | Python 3.10+
- Developer:
J Berendt
- Email:
- Comments:
n/a
- Example:
For class-specific usage examples, please refer to the docstring for the following classes:
- class database.DBInterface(connstr: str, *args, **kwargs)[source]
This class holds the methods and properties which are used across all databases. This class is the primary entry-point for the database interface.
Database-specific functionality is provided by this class'
__new__()
method, which returns the appropriate instance of the lower-level database-specific class, depending on the connection string provided. Or, more specifically, thesqlalchemy.Engine
object created from the provided connection string.Note
Due to the way this class is created - for specific design reasons - the inheriting class'
__init__
method will not be called. Therefore, specialisation is not as simple as inheritance and calling thesuper()
function.See the examples below for a use-case in how to specialise this class with your own methods.
- Parameters:
connstr (str) -- The database-specific SQLAlchemy connection string.
- Example Use:
This low-level generalised class is designed to be instantiated by local program or database module, as:
>>> from dblib.database import DBInterface >>> dbi = DBInterface(connstr=('mysql+mysqlconnector://' '<user>:<pwd>@<host>:<port>/' '<db_name>')) >>> dbi.engine Engine(mysql+mysqlconnector://<user>:***@<host>:<port>/db_name)
For example, the
dbi
instance can be used to execute a query, as:>>> result = dbi.execute_query('SELECT COUNT(*) FROM mytable'); >>> result [(14,)]
Additionally, the
dbi.engine
object can be supplied to thepandas.read_sql()
function'scon
parameter, as the database connection object, as:>>> import pandas as pd >>> sql = 'select count(*) from mytable' >>> df = pd.read_sql(sql, con=dbi.engine) >>> df count(*) 0 14
- Subclass Specialisation:
To specialise the subclass, a bit of 'pseudo-inheritance' is required due to the way the
DBInterface
class is created. A 'standard inheritance' with a call tosuper()
does not work, as the subclass'__init__
method is not called. Therefore, the subclass must add the parent's attributes into its class, manually.This can be done as follows:
from dblib.database import DBInterface class MyDBI: def __init__(self, connstr: str): # # Pseudo-inherit the DBInterface class by 'copying' # the attributes into this subclass. # # There are many ways to do this. This is the most # general, as functions, methods and properties are # captured. # self._dbi = DBInterface(connstr=connstr) fns = [fn for fn in dir(self._dbi) if not fn.startswith('__')] for fn in fns: setattr(self, fn, self._dbi.__getattribute__(fn)) @property def spam(self): return 'spam' # Continuation of class definition ... >>> db = MyDBI(connstr=('mysql+mysqlconnector://' '<user>:<pwd>@<host>:<port>/' '<db_name>')) # List the database interface class' attributes. # Notice that 'spam' is included in the list, along with the # methods from the :class:`DBInterface` class, thus # *simulating* inheritance. >>> dir(db) ['_PREFIX', '__class__', '__delattr__', ..., '__str__', '__subclasshook__', '__weakref__', '_connstr', '_create_engine', '_dbi', '_engine', '_report_sa_error', '_result_to_df__cursor', '_result_to_df__stored', 'call_procedure', 'call_procedure_update', 'call_procedure_update_many', 'call_procedure_update_raw', 'database_name', 'engine', 'execute_query', 'spam', # <--- 'table_exists']]
- _SUPPORTED_DBS = ['mysql', 'oracle', 'sqlite']
- static __new__(cls, connstr: str, *args, **kwargs)[source]
Provide a database interface based on the connection string.
Using the provided connection string, a
sqlalchemy.engine.base.Engine
object is created. Using the.name
attribute, an instance of the associated database interface class is returned.For example, if the
.name
attribute is'mysql'
, an instance of the_dbi_mysql._DBIMySQL
private interface class is returned. Likewise, if the.name
attribute is'oracle'
, an instance of the_dbi_oracle._DBIOracle
private interface class is returned, etc.- Parameters:
connstr (str) -- The SQLAlchemy-syle connection string, from which the
sqlalchemy.engine.base.Engine
is created for the database interface instance.
- static _create_engine__internal_only(connstr: str) str [source]
Create a database engine using the provided connection string.
Warning
This method is not to be called independently as:
The engine itself is not returned.
The connect is disposed immediately after creation.
The
pool_*
objects are not set.
The engine created here is only meant to providing database-class routing for this class'
__new__()
method.- Parameters:
connstr (str) -- The SQLAlchemy connection string.
- Returns:
The value of the
.name
attribute from the database engine.- Return type:
str