ae.db_core
database connection and data manipulation base classes
This module is providing generic base classes and helper methods to implement and integrate any database driver that is compatible to the Python DB API. The base classes are providing already all attributes and methods to handle database connections, data selections and manipulations.
Additionally this package is defining generalized interfaces to switch dynamically between databases without the need to adapt the code of your application - simply by selecting another database connector class within your configuration files.
basic usage
The abstract base class DbBase
allows you to implement a db-specific class with few
lines of code. Simply inherit from DbBase
and implement a connect()
method that is setting the conn
instance attribute to a
Python DB API compatible connection object.
For a fictive specific database driver package SpecificDbDriver that is providing a connect method, a minimal example would look like:
from ae.db_core import DbBase
...
class SpecificDb(DbBase):
def connect(self) -> str:
self.last_err_msg = ''
try:
self.conn = SpecificDbDriver.connect(**self.connect_params())
except Exception as ex:
self.last_err_msg = f"SpecificDb-connect() error: {ex} for {self}"
else:
self.create_cursor()
return self.last_err_msg
The helper method connect_params()
provided by this module is helping you to merge
any specified database system credentials and features into a dict to be passed as connection parameters
to the database-specific connection class/function/factory of the database driver.
Another helper create_cursor()
provided by DbBase
can be used in the
connect()
method to create a Python DB API-compatible cursor object and
assign it to the curs
attribute.
In this implementation your class SpecificDb does automatically also inherit useful methods from DbBase
to execute INSERT
, DELETE
,
UPDATE
and UPSERT
commands,
to run SELECT
queries and
to call stored procedures
.
connection parameters
DbBase
supports the following connection parameter keys:
user : user name or database account name.
password : user account password.
dbname : name of the database to connect.
host : host name or IP address of the database server.
port: port number of the database server.
Some database drivers are using default values for most of these connection parameters, if they are not specified. The mandatory connection parameters can differ for different database drivers. Most of them need at least a user name and password.
Hint
Most database drivers like e.g. psycopg2 or
pg8000 for Postgres databases
are supporting all of these connection parameter keys. For others like e.g.
cx_Oracle which are not supporting
some of them (like e.g. host and dbname) you may also need to overwrite the
connect_params()
method to convert/adopt unsupported connection parameter keys.
Alternatively you can provide the connection parameters needed by the database driver connector with a single database url string in the SQLAlchemy Database URL format:
dialect+driver://user:password@host:port/dbname
So if your connection parameters dict - respective your database system credentials and features -
providing a url key then connect_params()
will parse and split the url into
separate connection parameters.
Note
When you specify a connection parameter as separate key and also within the url value then the separate key value will have preference. The scheme part (dialect+driver) including the following colon character of the URL string are not evaluated and can be omitted.
bind variables format
Bind variables in your sql query strings have to be formatted in the
named parameter style. If your database driver is only supporting the
pyformat parameter style, then overload the __init__ method and set the param_style
to 'pyformat'
and all sql query strings will be automatically converted by DbBase
before they get sent to the database:
class SpecificDb(DbBase):
def __init__(self, ...)
super().__init__(...)
self.param_style = 'pyformat'
...
Module Attributes
character to mark a bind variable in a sql query |
|
bind variable name prefix, to allow for same column/-name a new/separate value in e.g. |
Functions
|
split dict with database connection parameters into credentials and features. |
Classes
|
abstract database connector base class for the ae namespace database system layers. |
- CHK_BIND_VAR_PREFIX: str = 'CV_'
bind variable name prefix, to allow for same column/-name a new/separate value in e.g. the SET clause and an old value in the WHERE clause. Gets added to bind variables in filters/chk_values and extra where clauses.
- connect_args_from_params(conn_params)[source]
split dict with database connection parameters into credentials and features.
- _prepare_in_clause(sql, bind_vars=None, additional_col_values=None)[source]
replace list bind variables used in an IN clause with separate bind variables for each list item.
- Parameters:
- Return type:
- Returns:
tuple of adapted query string and joined bind variables.
- _rebind(chk_values=None, where_group_order='', bind_vars=None, extra_bind=None)[source]
merge where_group_order string with chk_values filter dict and merge/rename bind variables.
- Parameters:
chk_values¶ (
Optional
[Dict
[str
,Any
]]) –dict with column_name: value items, used to filter/restrict the resulting rows.
This method compiles this dict into a sql WHERE clause expression. If you also passed additional sql clauses into the
where_group_order
then it will be merged with the compiled expression. The names of the sql parameters and related bind variables are build from the column names/keys of this dict, and will be prefixed withCHK_BIND_VAR_PREFIX
.Passing None or a empty dict to this and to the
extra_bind
arguments will disable any filtering. If only this argument is None/empty then the first item of theextra_bind
dict will be used as filter.where_group_order¶ (
str
) – sql part with optional WHERE/GROUP/ORDER clauses (the part after the WHERE), including bind variables in the named parameter style.bind_vars¶ (
Optional
[Dict
[str
,Any
]]) – dict with bind variables (variable name has to be prefixed inwhere_group_order
withCHK_BIND_VAR_PREFIX
).extra_bind¶ (
Optional
[Dict
[str
,Any
]]) – additional dict with bind variables (variable name has NOT to be prefixed/adapted inwhere_group_order
argument).
- Return type:
- Returns:
tuple of corrected/rebound values of chk_values, where_group_order and bind_vars.
- class DbBase(system)[source]
Bases:
SystemConnectorBase
,ABC
abstract database connector base class for the ae namespace database system layers.
This class inherits from
SystemConnectorBase
the following attributes:system: instance of the related
ae-sys_core.SystemBase
class.console_app: instance of the
application
using this database system.last_err_msg: the error message string of the last error or an empty string if no error occurred in the last database action/operation.
- __init__(system)[source]
create instance of generic database object (base class for real database like e.g. postgres or oracle).
- Parameters:
system¶ (
SystemBase
) –SystemBase
instance. Providing useful attributes, like e.g.:credentials: dict with database driver specific account credentials.
features: list of features. Features will also be passed as connection parameters to the database driver. The main differences to credentials are that a feature without any value will be interpreted as boolean True and that features can have any value that can be specified as a literal (like int or even datetime).
console_app: instance of the
application
using this database system.
- conn
database driver connection
- curs
database driver cursor
- _adapt_sql(sql, bind_vars)[source]
replace the parameter style of bind variables from pyformat into named.
- Parameters:
- Return type:
- Returns:
adapted query string.
Note
For database drivers - like psycopg2 - that are support only the pyformat parameter style syntax (in the format
%(bind_var)s
) the sql query string will be adapted, by converting all bind variables from the parameter style named into pyformat.The returned query will be unchanged for all other database drivers (that are directly supporting the named parameter style).
- call_proc(proc_name, proc_args, ret_dict=None)[source]
execute stored procedure on database server.
- Parameters:
- Return type:
- Returns:
empty string if no error occurred else the error message.
- connect_params()[source]
merges self.system.credentials with self.system.features into a database driver connection parameters dict.
- Return type:
- Returns:
new dict with the items from self.system.credentials and then extended with the entries of self.system.features.
Credential values are always of type str, only features can be of any type. Features without a specified value are set True. All keys of the returned dict will be in lower-case.
- cursor_description()[source]
return description text if opened cursor or None if cursor is closed or not yet opened.
- fetch_value(col_idx=0)[source]
fetch the value of a column of the first/next row of the found rows of the last SELECT query.
- execute_sql(sql, commit=False, bind_vars=None)[source]
execute sql query with optional bind variables.
- delete(table_name, chk_values=None, where_group_order='', bind_vars=None, commit=False)[source]
execute a DELETE command against a table.
- Parameters:
chk_values¶ (
Optional
[Dict
[str
,Any
]]) – dict of column names/values to identify the record(s) to delete.where_group_order¶ (
str
) – extra sql added after the WHERE clause (merged with chk_values by_rebind()
). This string can include additional WHERE expressions with extra bind variables.bind_vars¶ (
Optional
[Dict
[str
,Any
]]) – dict of extra bind variables (key=variable name, value=value).commit¶ (
bool
) – bool value to specify if commit should be done. Pass True to commit.
- Return type:
- Returns:
last error message or empty string if no errors occurred.
- insert(table_name, col_values, returning_column='', commit=False)[source]
execute an INSERT command to add one record to a database table.
- Parameters:
- Return type:
- Returns:
last error message or empty string if no errors occurred.
- select(from_join='', cols=(), chk_values=None, where_group_order='', bind_vars=None, hints='')[source]
execute a SELECT query against a database table.
- Parameters:
from_join¶ (
str
) – name(s) of the involved database table(s), optional with JOIN clause(s). Passing an empty string results in a SELECT statement without the FROM keyword.cols¶ (
Sequence
[str
]) – sequence of the column names that will be selected and included in the resulting data-rows.chk_values¶ (
Optional
[Dict
[str
,Any
]]) – dict of column names/values to identify selected record(s).where_group_order¶ (
str
) – extra sql added after the WHERE clause (merged with chk_values by_rebind()
). This string can include additional WHERE expressions with extra bind variables, ORDER BY and GROUP BY expressions. These special/extra bind variables have to be specified in thebind_vars
argument and have to be prefixed with the string ‘CV_’ in the WHERE clause (see also theCHK_BIND_VAR_PREFIX
data constant in this module).bind_vars¶ (
Optional
[Dict
[str
,Any
]]) – dict of extra bind variables (key=variable name, value=value).
- Return type:
- Returns:
last error message or empty string if no errors occurred. Use the methods
fetch_all()
orfetch_value()
to retrieve the resulting data-rows.
- update(table_name, col_values, chk_values=None, where_group_order='', bind_vars=None, commit=False, locked_cols=())[source]
execute an UPDATE command against a database table.
- Parameters:
col_values¶ (
Dict
[str
,Any
]) – dict of inserted/updated column values with the column name as key.chk_values¶ (
Optional
[Dict
[str
,Any
]]) – dict of column names/values to identify affected record(s). If not passed then the first name/value ofcol_values
is used as primary key check/filter value.where_group_order¶ (
str
) – extra sql added after the WHERE clause (merged with chk_values by_rebind()
). This string can include additional WHERE expressions with extra bind variables, ORDER BY and GROUP BY expressions. These special/extra bind variables have to be specified in thebind_vars
argument and have to be prefixed with the string ‘CV_’ (see also theCHK_BIND_VAR_PREFIX
data constant in this module).bind_vars¶ (
Optional
[Dict
[str
,Any
]]) – dict of extra bind variables (key=variable name, value=value).commit¶ (
bool
) – bool value to specify if commit should be done. Pass True to commit.locked_cols¶ (
Sequence
[str
]) – list of column names not be overwritten on update of column value is not empty.
- Return type:
- Returns:
last error message or empty string if no errors occurred.
- upsert(table_name, col_values, chk_values, where_group_order='', bind_vars=None, returning_column='', commit=False, locked_cols=(), multiple_row_update=True)[source]
execute an INSERT or UPDATE command against a record of a database table (UPDATE if record already exists).
- Parameters:
col_values¶ (
Dict
[str
,Any
]) – dict of inserted/updated column values with the column name as key.chk_values¶ (
Dict
[str
,Any
]) – dict of column names/values to identify affected record(s), also used to check if record already exists (and data has to updated instead of inserted). If not passed then the first name/value of col_values is used as primary key check/filter value.where_group_order¶ (
str
) – extra sql added after the WHERE clause (merged with chk_values by_rebind()
). This string can include additional WHERE expressions with extra bind variables, ORDER BY and GROUP BY expressions. These special/extra bind variables have to be specified in thebind_vars
argument and have to be prefixed with the string ‘CV_’ in the query string (see also theCHK_BIND_VAR_PREFIX
data constant in this module).bind_vars¶ (
Optional
[Dict
[str
,Any
]]) – dict of extra bind variables (key=variable name, value=value).returning_column¶ (
str
) – name of column which value will be returned by next fetch_all/fetch_value() call.commit¶ (
bool
) – bool value to specify if commit should be done. Pass True to commit record changes.locked_cols¶ (
Sequence
[str
]) – list of column names not be overwritten on update of column value is not empty.multiple_row_update¶ (
bool
) – allow update of multiple records with the same chk_values.
- Return type:
- Returns:
last error message or empty string if no errors occurred.
- commit(reset_last_err_msg=False)[source]
commit the current transaction if the database driver supports/implements a commit method.
- rollback(reset_last_err_msg=False)[source]
roll the current transaction back if the DB driver supports transactions and does have a rollback method.
- get_row_count()[source]
determine rowcount of last executed query.
- Return type:
- Returns:
the number of affected rows of the last query.
- static thread_lock_init(table_name, chk_values)[source]
created named locking instance for passed table and filter/check expression.
- Return type:
- Returns:
NamedLocks
instance for this table and filter.