zensols.db package¶
Submodules¶
zensols.db.bean module¶
Basic CRUD utility classes
- class zensols.db.bean.Bean[source]¶
Bases:
object
A container class like a Java bean.
- __init__()¶
- get_insert_row()[source]¶
Return a row of data meant to be inserted into the database. This method implementation leaves off the first attriubte assuming it contains a unique (i.e. row ID) of the object. See
get_row()
.
- get_row()[source]¶
Return a row of data meant to be printed. This includes the unique ID of the bean (see
get_insert_row()
).
- class zensols.db.bean.BeanDbPersister(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None, insert_name=None, update_name=None, delete_name=None, keys_name=None, count_name=None)[source]¶
Bases:
UpdatableBeanDbPersister
A class that contains the remaining CRUD funtionality the super class doesn’t have.
- __init__(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None, insert_name=None, update_name=None, delete_name=None, keys_name=None, count_name=None)¶
- class zensols.db.bean.DbPersister(conn_manager, sql_file=None, row_factory='tuple')[source]¶
Bases:
AbstractDbPersister
CRUDs data to/from a DB-API connection.
- __init__(conn_manager, sql_file=None, row_factory='tuple')¶
- execute_by_name(name, params=(), row_factory=None, map_fn=None)[source]¶
Just like
execute()
but look up the SQL statement to execute on the database connection.The
row_factory
tells the method how to interpret the row data in to an object that’s returned. It can be one of:tuple
: tuples (the default)dict
: for dictionariespandas
: for apandas.DataFrame
otherwise: a function or class
Compare this with
map_fn
, which transforms the data that’s given to therow_factory
.
- execute_no_read(**kwargs) int ¶
Just like
execute_by_name()
, but return database level information such as row IDs rather than the results of a query. Use this when inserting data to get a row ID.- Parameters:
entry_name – the key in the SQL file whose value is used as the statement
capture_rowid – if
True
, return the last row ID from the cursor
- See:
- Return type:
- execute_singleton_by_name(*args, **kwargs)[source]¶
Just like
execute_by_name()
except return only the first item orNone
if no results.
- execute_sql_no_read(**kwargs) int ¶
Execute SQL and return the database level information such as row IDs rather than the results of a query. Use this when inserting data to get a row ID.
- Return type:
-
row_factory:
Union
[str
,Type
] = 'tuple'¶ The default method by which data is returned from
execute_*
methods.- See:
execute()
.
- class zensols.db.bean.InsertableBeanDbPersister(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None, insert_name=None)[source]¶
Bases:
ReadOnlyBeanDbPersister
A class that contains insert funtionality.
- __init__(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None, insert_name=None)¶
- insert(bean)[source]¶
Insert a bean using the order of the values given in
Bean.get_insert_row()
as that of the SQL defined with entryinsert_name
given in the initializer.- Return type:
- insert_beans(beans, errors='raise')[source]¶
Insert a bean using the order of the values given in
Bean.get_insert_row()
as that of the SQL defined with entryinsert_name
given in the initializer.- Return type:
- insert_dataframe(**kwargs) int ¶
Like
insert_rows()
but the data is taken a Pandas dataframe.- Parameters:
df – the dataframe from which the rows are drawn
set_id_fn – a callable that is given the data to be inserted and the row ID returned from the row insert as parameters
map_fn – if not
None
, used to transform the given row in to a tuple that is used for the insertionchuck_size – the number of rows inserted at a time, so the number of interactions with the database are at most the row count of the dataframe / ``chunk_size``x
- Return type:
- Returns:
the
rowid
of the last row inserted
- insert_row(*row)[source]¶
Insert a row in the database and return the current row ID.
- Parameters:
row – a sequence of data in column order of the SQL provided by the entry
insert_name
- Return type:
- insert_rows(**kwargs) int ¶
Insert a tuple of rows in the database and return the current row ID.
- Parameters:
rows – a sequence of tuples of data (or an object to be transformed, see
map_fn
in column order of the SQL provided by the entryinsert_name
errors – if this is the string
raise
then raise an error on any exception when invoking the database executeset_id_fn – a callable that is given the data to be inserted and the row ID returned from the row insert as parameters
map_fn – if not
None
, used to transform the given row in to a tuple that is used for the insertion
- Return type:
- Returns:
the
rowid
of the last row inserted
- class zensols.db.bean.ReadOnlyBeanDbPersister(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None)[source]¶
Bases:
DbPersister
A read-only persister that CRUDs data based on predefined SQL given in the configuration. The class optionally works with instances of
Bean
whenrow_factory
is set to the target bean class.- __init__(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None)¶
- exists(id)[source]¶
Return
True
if there is a object with unique ID (or row ID) in the database. Otherwise returnFalse
.- Return type:
- get()[source]¶
Return using the SQL provided by the entry identified by
select_name
.- Return type:
- get_by_id(id)[source]¶
Return an object using it’s unique ID, which is could be the row ID in SQLite.
- class zensols.db.bean.UpdatableBeanDbPersister(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None, insert_name=None, update_name=None, delete_name=None)[source]¶
Bases:
InsertableBeanDbPersister
A class that contains the remaining CRUD funtionality the super class doesn’t have.
- __init__(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None, insert_name=None, update_name=None, delete_name=None)¶
zensols.db.conn module¶
Domain classes.
- class zensols.db.conn.AbstractDbPersister(conn_manager)[source]¶
Bases:
object
An abstract class to CRUD data with basic operations and a connection to the database.
- __init__(conn_manager)¶
-
conn_manager:
ConnectionManager
¶ Used to create DB-API connections.
- execute(**kwargs) Tuple[dict | tuple | pd.DataFrame] ¶
Execute SQL on a database connection.
The
row_factory
tells the method how to interpret the row data in to an object that’s returned. It can be one of:tuple
: tuples (the default)dict
: for dictionariespandas
: for apandas.DataFrame
otherwise: a function or class
Compare this with
map_fn
, which transforms the data that’s given to therow_factory
.- Parameters:
sql – the string SQL to execute
params – the parameters given to the SQL statement (populated with
?
) in the statementrow_factory –
tuple
,dict
,pandas
or a functionmap_fn – a function that transforms row data given to the
row_factory
- Return type:
Tuple[Union[dict, tuple, pd.DataFrame]]
- class zensols.db.conn.ConnectionManager[source]¶
Bases:
object
Instance DB-API connection lifecycle.
- __init__()¶
- abstract drop()[source]¶
Remove all objects from the database or the database itself.
For SQLite, this deletes the file. In database implementations, this might drop all objects from the database. Regardless, it is expected that
create
is able to recreate the database after this action.- Return type:
- Returns:
whether the database was dropped
- execute(conn, sql, params, row_factory, map_fn)[source]¶
Execute SQL on a database connection.
The
row_factory
tells the method how to interpret the row data in to an object that’s returned. It can be one of:tuple
: tuples (the default)identity
: return the unmodified form from the databasedict
: for dictionariespandas
: for apandas.DataFrame
otherwise: a function or class
Compare this with
map_fn
, which transforms the data that’s given to therow_factory
.- Parameters:
conn (
Any
) – the connection object with the databasesql (
str
) – the string SQL to executeparams (
Tuple
[Any
,...
]) – the parameters given to the SQL statement (populated with?
) in the statementrow_factory (
Union
[str
,Callable
]) –tuple
,dict
,pandas
or a functionmap_fn (
Callable
) – a function that transforms row data given to therow_factory
- See:
DbPersister.execute()
.- Return type:
- execute_no_read(conn, sql, params)[source]¶
Return database level information such as row IDs rather than the results of a query. Use this when inserting data to get a row ID.
- insert_rows(conn, sql, rows, errors, set_id_fn, map_fn)[source]¶
Insert a tuple of rows in the database and return the current row ID.
- Parameters:
rows (
Iterable
[Any
]) – a sequence of tuples of data (or an object to be transformed, seemap_fn
in column order of the SQL provided by the entryinsert_name
errors (
str
) – if this is the stringraise
then raise an error on any exception when invoking the database execute, otherwise useignore
to ignore errorsset_id_fn (
Callable
) – a callable that is given the data to be inserted and the row ID returned from the row insert as parametersmap_fn (
Callable
) – if notNone
, used to transform the given row in to a tuple that is used for the insertion
- Return type:
- Returns:
the
rowid
of the last row inserted
- register_persister(persister)[source]¶
Register the persister used for this connection manager.
- Parameters:
persister (
AbstractDbPersister
) – the persister used for connection management
- exception zensols.db.conn.DBError[source]¶
Bases:
APIError
“Raised for all
zensols.db`
related errors.- __module__ = 'zensols.db.conn'¶
- class zensols.db.conn.connection[source]¶
Bases:
resource
Annotation used to create and dispose of DB-API connections.
- class zensols.db.conn.cursor(persister, sql=None, name=None, params=())[source]¶
Bases:
object
Iterate through rows of a database. The connection is automatically closed once out of scope.
Example:
config_factory: ConfigFactory = ... persister: DbPersister = config_factory.instance('person_db_persister') with cursor(persister, name='select_people') as c: for row in c: print(row)
- __init__(persister, sql=None, name=None, params=())[source]¶
Initialize with either
name
orsql
(only one should beNone
).- Parameters:
persister (
AbstractDbPersister
) – used to execute the SQL and obtain the cursorsql (
str
) – the string SQL to executename (
str
) – the named SQL query in theDbPersister.sql_file
params (
Tuple
[Any
,...
]) – the parameters given to the SQL statement (populated with?
) in the statement
zensols.db.connpool module¶
Connection pool.
- class zensols.db.connpool.PooledConnectionManager(delegate, size=1)[source]¶
Bases:
ConnectionManager
Pools database connections.
- __init__(delegate, size=1)¶
-
delegate:
ConnectionManager
¶ The delegate manager that controls the lifecycle of pooled connections.
- drop()[source]¶
Remove all objects from the database or the database itself.
For SQLite, this deletes the file. In database implementations, this might drop all objects from the database. Regardless, it is expected that
create
is able to recreate the database after this action.- Return type:
- Returns:
whether the database was dropped
zensols.db.dataclass module¶
Contains utility classes to persist dataclasses.dataclass
.
- class zensols.db.dataclass.DataClassDbPersister(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None, insert_name=None, update_name=None, delete_name=None, keys_name=None, count_name=None, bean_class=None)[source]¶
Bases:
BeanDbPersister
Persists instances of
dataclasses.dataclass
by narrowing the columns from select statements. Instead ofselect *
, useselect ${cols}
in the SQL resource file.- __init__(conn_manager, sql_file=None, row_factory='tuple', select_name=None, select_by_id_name=None, select_exists_name=None, insert_name=None, update_name=None, delete_name=None, keys_name=None, count_name=None, bean_class=None)¶
- class zensols.db.dataclass.DataClassDynamicDataParser(dd_path, bean_class)[source]¶
Bases:
DynamicDataParser
An SQL data parser that replaces
${cols}
in the SQL file with thedataclasses.dataclass
fields.- See:
zensols.db.parse module¶
Simple parsing of a dynamic definition langauge (DDL) and dynamic manipulation language (DML) files.
- class zensols.db.parse.DynamicDataParser(dd_path)[source]¶
Bases:
object
Parse a DDL/DML file meant also for prototyping.
For example the file:
-- meta=init_sections=create_tables,create_idx -- name=create_idx create index person_name on person(name); -- name=create_tables create table person (id int, name text, age int);
Would have
create_idx
andcreate_tables
as sections and meta data:{'init_sections': 'create_tables,create_idx'}
zensols.db.sqlite module¶
Convenience wrapper for the Python DB-API library, and some specificly for the SQLite library.
- class zensols.db.sqlite.SqliteAttachConnectionManager(db_file, database_name)[source]¶
Bases:
ConnectionManager
An SQLite connection factory that attaches a file as a database.
- __init__(db_file, database_name)¶
- class zensols.db.sqlite.SqliteConnectionManager(db_file, create_db=True)[source]¶
Bases:
ConnectionManager
An SQLite connection factory.
- __init__(db_file, create_db=True)¶
- create()[source]¶
Create a connection by accessing the SQLite file.
- Raises:
DBError – if the SQLite file does not exist (caveat see :obj:create_db)
- Return type:
zensols.db.stash module¶
Adapt a database centric DbPersister
to a general
Stash
container.
- class zensols.db.stash.AlternateKeyBeanStash(persister, key_to_id_name, keys_name)[source]¶
Bases:
BeanStash
A stash that uses another key rather than some unique primary key (i.e. rowid for SQLite). It does this by looking up the alternate key in some other column and resolves to the unique primary key.
The domain and range of the function (
_key_to_id()
) that maps alternate keys to unique primary keys ate strings.- __init__(persister, key_to_id_name, keys_name)¶
- delete(name)[source]¶
Delete the resource for data pointed to by
name
or the entire resource ifname
is not given.
- dump(name, inst)[source]¶
Since this implementation can let the database auto-increment the unique/primary key, beware of “changing” keys.
- Raises:
DBError – if the key changes after inserted it will raise a
DBError
; for this reason, it’s best to passNone
asname
- exists(name)[source]¶
Return
True
if data with keyname
exists.Implementation note: This
Stash.exists()
method is very inefficient and should be overriden.- Return type:
- class zensols.db.stash.BeanStash(persister)[source]¶
Bases:
Stash
A stash that uses a backing DB-API backed
BeanDbPersister
.- __init__(persister)¶
- delete(name)[source]¶
Delete the resource for data pointed to by
name
or the entire resource ifname
is not given.
- dump(name, inst)[source]¶
Since this implementation can let the database auto-increment the unique/primary key, beware of “changing” keys.
- Raises:
DBError – if the key changes after inserted it will raise a
DBError
; for this reason, it’s best to passNone
asname
- exists(name)[source]¶
Return
True
if data with keyname
exists.Implementation note: This
Stash.exists()
method is very inefficient and should be overriden.- Return type:
- load(name)[source]¶
Load a data value from the pickled data with key
name
. Semantically, this method loads the using the stash’s implementation. For exampleDirectoryStash
loads the data from a file if it exists, but factory type stashes will always re-generate the data.- See:
get()
- Return type:
-
persister:
BeanDbPersister
¶ The delegate bean persister.
- class zensols.db.stash.DbStash(encoder_decoder=<factory>)[source]¶
Bases:
Stash
A relational database to store stash keys and values. It creates a single table with only two columns: one for the (string) key and the other for the values.
- __init__(encoder_decoder=<factory>)¶
- clear()[source]¶
Delete all data from the from the stash.
Important: Exercise caution with this method, of course.
- delete(name)[source]¶
Delete the resource for data pointed to by
name
or the entire resource ifname
is not given.
- dump(name, inst)[source]¶
Since this implementation can let the database auto-increment the unique/primary key, beware of “changing” keys.
- Raises:
DBError – if the key changes after inserted it will raise a
DBError
; for this reason, it’s best to passNone
asname
-
encoder_decoder:
DbStashEncoderDecoder
¶ Used to encode and decode the data with the SQLite database. To use binary data, set this to an instance of
This should be set to:
DbStashEncoderDecoder
: store text valuesPickleDbStashEncoderDecoder
: store binary data (default)jsonpickle
: store JSON (needspip install jsonpickle
); useencoder_decoder = eval({'import': ['jsonpickle']}): jsonpickle
in application configurations
You can write your own by extending
DbStashEncoderDecoder
.
- exists(name)[source]¶
Return
True
if data with keyname
exists.Implementation note: This
Stash.exists()
method is very inefficient and should be overriden.- Return type:
- load(name)[source]¶
Load a data value from the pickled data with key
name
. Semantically, this method loads the using the stash’s implementation. For exampleDirectoryStash
loads the data from a file if it exists, but factory type stashes will always re-generate the data.- See:
get()
- Return type:
- property persister: BeanDbPersister¶
The persister used to interface with the database.