SqlDbWrpr
| Category | Status' and Links |
|---|---|
| General | |
| CD/CI | |
| PyPI | |
| Github |
Short description
SqlDbWrpr is a Python wrapper that streamlines schema creation plus CSV import/export workflows for SQL backends.
Module Overview
SqlDbWrpr is a Python utility for creating SQL database schemas and moving CSV data into and out of those schemas. It currently provides wrappers for MySQL and PostgreSQL.
Schemas can be supplied in two ways:
- A legacy
db_structuredictionary. - SQLAlchemy metadata, either directly through
p_sqlalchemy_metadataor throughp_sqlalchemy_base.metadata.
When both are supplied, p_db_structure takes precedence for backward compatibility. If no supported schema source is supplied, SchemaSourceError is raised.
Key Features
- Schema Management: Create databases, tables, primary keys, foreign keys, and indexes from a legacy dictionary or SQLAlchemy metadata.
- Data Import/Export:
- Import CSV data from files or in-memory rows, including single-volume and numbered multi-volume files.
- Export full tables or custom SQL query results to CSV, including optional multi-volume exports.
- Database Support: Includes MySQL and PostgreSQL wrappers with dialect-specific SQL rendering.
- User and Permission Management: Create and delete MySQL users or PostgreSQL login roles, and grant backend-specific database or table rights.
- Batch Processing: Configure import batch sizes for larger CSV loads.
Project Structure
src/sqldbwrpr/: Core library implementation, including MySQL and PostgreSQL wrappers.tests/: Unit and integration-oriented test coverage for wrapper behaviour.scripts/: SQL setup/bootstrap assets used for database initialization.- Root automation scripts (
*.ps1) and CI configuration under.github/workflows/support setup and delivery.
Getting Started
Installation
pip install SqlDbWrpr
Running the Tests
The focused database tests use temporary MySQL 8.0 and PostgreSQL 16 Docker containers. Ensure Docker is running, then install the development dependencies and run the test suite:
poetry install --with dev
poetry run pytest
The test fixtures wait for each database to become ready and remove the temporary containers after the test session.
Quick Start With A Legacy Structure
from sqldbwrpr.sqldbwrpr import MySQL
field_defaults = {
"PrimaryKey": ["", ""],
"FKey": [],
"Index": [],
"NN": "",
"B": "",
"UN": "",
"ZF": "",
"AI": "",
"G": "",
"DEF": "",
}
db_structure = {
"Users": {
"ID": {
"Type": ["int"],
"Params": {
**field_defaults,
"PrimaryKey": ["Y", "A"],
"NN": "Y",
"AI": "Y",
},
"Possible Values": "",
"Comment": "",
},
"Username": {
"Type": ["varchar", 50],
"Params": {**field_defaults, "NN": "Y"},
"Possible Values": "",
"Comment": "",
},
}
}
db = MySQL(
p_host_name="localhost",
p_user_name="root",
p_password="yourpassword",
p_db_name="my_database",
p_db_structure=db_structure,
p_recreate_db=True,
)
db.import_csv("Users", p_csv_db=[("Username",), ("alice",)], p_vol_type="Single")
db.export_to_csv("exported_users.csv", "Users")
Quick Start With SQLAlchemy Metadata
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import MetaData
from sqlalchemy import String
from sqlalchemy import Table
from sqldbwrpr.sqldbwrpr import PostgreSQL
metadata = MetaData()
Table(
"Users",
metadata,
Column("ID", Integer, primary_key=True, autoincrement=True),
Column("Username", String(50), nullable=False),
)
db = PostgreSQL(
p_host_name="localhost",
p_user_name="postgres",
p_password="yourpassword",
p_db_name="my_database",
p_sqlalchemy_metadata=metadata,
p_recreate_db=True,
)
db.import_csv("Users", p_csv_db=[("Username",), ("alice",)], p_vol_type="Single")
Function Reference
This section documents the callable API in src/sqldbwrpr/sqldbwrpr.py.
SchemaSourceError
SchemaSourceError(ValueError): Raised when no usable schema source is provided to initialize a wrapper (p_db_structure,p_sqlalchemy_metadata, orp_sqlalchemy_base.metadata).
SQLDbWrpr (base wrapper)
__init__(p_host_name, p_user_name, p_password, p_recreate_db, p_db_name, p_db_structure, p_sqlalchemy_base, p_sqlalchemy_metadata, p_batch_size, p_bar_len, p_msg_width, p_verbose, p_db_port, p_ssl_ca, p_ssl_key, p_ssl_cert)- Initializes shared wrapper state, resolves schema source, configures import/export behavior, and precomputes char vs non-char field maps.
- Schema resolution order: explicit
p_db_structurefirst, then SQLAlchemy metadata, else raisesSchemaSourceError.
close()- Closes the active DB connection if present.
build_column_sql(p_field_name, p_field_type, p_field_params, p_field_comment)- Builds the column fragment for
CREATE TABLEin the active dialect (base implementation is MySQL-oriented). - Applies
AUTO_INCREMENT,UNSIGNED,NOT NULL,ZEROFILL, defaults, and comments based on field parameters.
- Builds the column fragment for
build_index_sql(p_table_name, p_idx_name, p_idx_fields, p_unique=False)- Builds an index clause with sort directions from legacy index metadata.
build_insert_sql(p_table_name, p_header, p_replace=False)- Builds an
INSERTorREPLACEstatement with backend parameter placeholders.
- Builds an
param_placeholder()- Returns the DB-API parameter token used by execution (
%s).
- Returns the DB-API parameter token used by execution (
quote_identifier(p_identifier)- Quotes SQL identifiers when a backend quote character is configured; otherwise returns plain identifier text.
quote_identifier_list(p_identifiers)- Quotes and joins a list of identifiers using commas.
render_default_sql(p_field_type, p_default_value)- Renders a
DEFAULTclause, quoting string-like defaults for char/varchar types.
- Renders a
render_field_type(p_field_type, p_field_params)- Renders legacy type arrays into SQL type declarations (e.g.,
varchar(n),decimal(p,s)).
- Renders legacy type arrays into SQL type declarations (e.g.,
create_db()- Base database recreation flow: drops an existing DB and creates/selects a fresh one.
create_tables()- Validates legacy schema metadata and creates tables, keys, indexes, and constraints in dependency order.
- Splits table creation and post-create operations where backend rules require deferred statements.
create_users(p_admin_user, p_new_users)- Creates MySQL users if they do not already exist.
delete_users(p_admin_user, p_del_users)- Drops MySQL users that exist in
mysql.user.
- Drops MySQL users that exist in
_err_broken_rec(p_sql_str, p_csv_db_slice)- Retry helper used during imports to isolate/log failing rows and stop on first unrecoverable record.
export_to_csv(p_csv_path, p_table_name, p_delimiter="|", p_strip_chars="", p__vol_size=0, p_sql_query="")- Exports table/query results to CSV in single-file or multi-volume mode.
- Multi-volume mode chunks output by record count and generates numbered files.
get_db_field_types()- Populates per-table lists of character vs non-character columns for type-sensitive import handling.
grant_rights(p_admin_user, p_user_rights)- Grants MySQL rights and corresponding grant-option privileges according to supplied rights tuples.
import_csv(p_table_name, p_csv_file_name="", p_key="", p_header="", p_del_head=False, p_csv_db="", p_csv_corr_str_file_name="", p_vol_type="Multi", p_verbose=False, p_replace=False)- Imports CSV data from file(s) or in-memory rows.
- Supports single- and multi-volume input, optional header override/removal, correction-string preprocessing, type conversion, date normalization, and batched insert/replace.
import_and_split_csv(p_split_struct, p_data, p_header="", p_insert_header=False, p_verbose=False, p_debug=False)- Splits an input dataset into multiple destination table payloads using declarative field mappings and transform commands, then imports each generated dataset.
from_sqlalchemy_metadata(p_sqlalchemy_metadata)(@classmethod)- Converts SQLAlchemy
MetaData(sorted tables) to the legacydb_structuredictionary.
- Converts SQLAlchemy
resolve_db_structure(p_db_structure=None, p_sqlalchemy_base=None, p_sqlalchemy_metadata=None)(@staticmethod)- Central schema source resolver used by constructors; raises
SchemaSourceErrorwhen none are provided.
- Central schema source resolver used by constructors; raises
_action_to_legacy_code(p_action)(@staticmethod)- Maps SQLAlchemy FK action text (e.g.,
CASCADE,SET NULL) to legacy action codes (C,N, etc.).
- Maps SQLAlchemy FK action text (e.g.,
_build_default_field_params()(@staticmethod)- Produces the baseline legacy field-parameter block used during SQLAlchemy conversion.
_column_type_to_legacy(p_column)(@staticmethod)- Converts a SQLAlchemy column type object into the legacy type-array format.
_column_to_legacy_field(p_column)(@staticmethod)- Converts one SQLAlchemy column into a legacy field definition, including nullability, autoincrement, defaults, and comments.
_set_foreign_keys(p_table, p_table_structure)(@staticmethod)- Writes legacy foreign-key metadata onto converted table fields.
_set_indexes(p_table, p_table_structure)(@staticmethod)- Writes legacy index metadata for converted table fields.
_set_primary_key(p_table, p_table_structure)(@staticmethod)- Marks primary-key columns in converted legacy table definitions.
_table_to_legacy_structure(p_table)(@staticmethod)- Converts an entire SQLAlchemy table into a legacy table structure and enriches it with keys/indexes.
_print_err_msg(p_err, p_msg="")(@staticmethod)- Formats and prints database error details before termination paths.
MySQL(SQLDbWrpr)
__init__(p_host_name, p_user_name, p_password, p_user_rights, p_recreate_db, p_db_name, p_db_structure, p_sqlalchemy_base, p_sqlalchemy_metadata, p_batch_size, p_bar_len, p_msg_width, p_verbose, p_admin_username, p_admin_user_password, p_db_port, **kwargs)- Opens a MySQL connection and cursor, optionally recreates database/tables, or selects the configured DB.
- Includes fallback logic to create and grant rights to missing users when valid admin credentials and rights data are supplied.
PostgreSQL(SQLDbWrpr)
__init__(p_host_name, p_user_name, p_password, p_recreate_db, p_db_name, p_db_structure, p_sqlalchemy_base, p_sqlalchemy_metadata, p_batch_size, p_bar_len, p_msg_width, p_verbose, p_db_port, p_maintenance_db, **kwargs)- Configures PostgreSQL-specific behavior (quoted identifiers, non-inline indexes), opens connection, and optionally recreates DB/tables.
build_column_sql(p_field_name, p_field_type, p_field_params, p_field_comment)- PostgreSQL-specific column SQL renderer; handles non-AI
NOT NULLand defaults.
- PostgreSQL-specific column SQL renderer; handles non-AI
build_index_sql(p_table_name, p_idx_name, p_idx_fields, p_unique=False)- Builds PostgreSQL
CREATE INDEX/CREATE UNIQUE INDEXstatements.
- Builds PostgreSQL
build_insert_sql(p_table_name, p_header, p_replace=False)- Builds PostgreSQL
INSERT; whenp_replace=True, buildsON CONFLICTupsert/no-op behavior from primary-key metadata.
- Builds PostgreSQL
create_db()- PostgreSQL DB recreation flow via
pg_databaselookup, optional forced drop, create, and reconnect.
- PostgreSQL DB recreation flow via
create_users(p_admin_user, p_new_users)- Creates PostgreSQL login roles that do not already exist, using the supplied passwords.
delete_users(p_admin_user, p_del_users)- Drops PostgreSQL roles that currently exist.
grant_rights(p_admin_user, p_user_rights)- Grants database-level rights when the table target is
*; otherwise grants table-level rights. PostgreSQL ignores the host field in each rights entry.
- Grants database-level rights when the table target is
render_default_sql(p_field_type, p_default_value)- Renders PostgreSQL defaults with proper escaping for string values.
render_field_type(p_field_type, p_field_params)- Maps legacy types to PostgreSQL types, including
SERIAL/BIGSERIALfor autoincrement fields.
- Maps legacy types to PostgreSQL types, including
_connect(p_db_name)- Internal connector helper returning a
psycopgconnection for the requested database.
- Internal connector helper returning a
Updating ReleaseNotes Instructions
- Run the
pushpy.ps1script or manually commit the current changes. - Generate the release notes
- Use one of the following AI propmpts in Notion to generate the release notes.
or
-
Use the following template and manually update the ReleaseNotes.md file.
# Release ?.?.? ## Summary of Changes - bla, bla, bla ## Next Heading - bla, bla, bla --- -
You can repeat step 1 multiple times.
-
You can repeat step 2 multiple times but update the ReleaseNotes that has not been published.
-
Run the
pushpr.ps1script once you are ready to create the PR to publish the release. TOy can also manually create the tag, touch a file, commit and push the changes. -
Merge the PR in GitHub.
-
Confirm the following:
-
The release update reflects in GitHub
-
The release update notification was sent
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sqldbwrpr-5.1.1.tar.gz.
File metadata
- Download URL: sqldbwrpr-5.1.1.tar.gz
- Upload date:
- Size: 28.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.4.1 CPython/3.13.14 Linux/6.17.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7e7bac85daa8ef4c6ac5fdbd96db83f57534b5b03f09ace2dda1843f11a6a2a
|
|
| MD5 |
f6fd1e9211146ed120e395a9c8859a01
|
|
| BLAKE2b-256 |
17ddfa1320ce30b8686581926f54dc8cf18b72890d01c1c012d3f4fabf20fed1
|
File details
Details for the file sqldbwrpr-5.1.1-py3-none-any.whl.
File metadata
- Download URL: sqldbwrpr-5.1.1-py3-none-any.whl
- Upload date:
- Size: 23.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.4.1 CPython/3.13.14 Linux/6.17.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b832b648107d8ae361b01657f223fd78c18a8c416e5537c47df5268224faba2f
|
|
| MD5 |
7b35109cdfb11fa55d5ff0f889a9f180
|
|
| BLAKE2b-256 |
c07a2c923231de00c710ccd5b97a871990cf7971b35486688219389d3eda55d5
|