Tools for waudit: SQL generation, Alembic ops, SQLAlchemy mixins
Project description
waudit-tools
Utilities for CDC-based audit log systems. SQL generation, custom Alembic operations, and SQLAlchemy mixins for PostgreSQL + Debezium pipelines.
Installation
With pip:
pip install waudit-tools
With uv:
uv pip install waudit-tools
Requires Python 3.11+.
Quick Start
Alembic migration (recommended)
Create an empty migration:
alembic revision -m "setup waudit"
upgrade:
from alembic import op
from myproject.models import Base
def upgrade() -> None:
op.waudit_setup_from_base(
Base,
exclude={"alembic_version"},
create_heartbeat_table=True,
)
downgrade:
def downgrade() -> None:
op.waudit_remove_from_base(
Base,
exclude={"alembic_version"},
drop_heartbeat_table=True,
)
Use Cases
1. Manual table list
When you don't use a declarative base or want full control:
def upgrade() -> None:
op.waudit_setup(
include_audit_tables=["users", "articles", "comments"],
exclude_audit_tables=["alembic_version", "spatial_ref_sys"],
create_heartbeat_table=True,
schema="public",
)
def downgrade() -> None:
op.waudit_remove(
include_audit_tables=["users", "articles", "comments"],
exclude_audit_tables=["alembic_version"],
drop_heartbeat_table=True,
schema="public",
)
2. Single table
For targeted changes or incremental rollout:
def upgrade() -> None:
op.waudit_setup_table("users", schema="public")
def downgrade() -> None:
op.waudit_remove_table("users", schema="public")
3. Raw SQL generation (no Alembic)
Generate SQL strings for external tooling or manual execution:
from waudit_tools.sql.identity import generate_identity_sql, apply_identity_to_tables
from waudit_tools.sql.heartbeat import generate_heartbeat_sql, generate_drop_heartbeat_sql
# Single table
sql = generate_identity_sql("users", schema="public")
# ALTER TABLE public.users REPLICA IDENTITY FULL;
# Batch
batch = apply_identity_to_tables(["users", "articles", "comments"], schema="cms")
# Heartbeat
create_hb = generate_heartbeat_sql(schema="public")
drop_hb = generate_drop_heartbeat_sql(schema="public")
4. SQLAlchemy model mixins
Add last_modified_by to your models:
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from waudit_tools.sqlalchemy.mixins.str_mixin import WAuditStrMixin
class Base(DeclarativeBase):
pass
class User(Base, WAuditStrMixin):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
# last_modified_by: str | None -- injected by mixin
For UUID-based actor tracking:
from waudit_tools.sqlalchemy.mixins.uuid_mixin import WAuditUUIDMixin
class User(Base, WAuditUUIDMixin):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
# last_modified_by: UUID | None -- injected by mixin
5. Programmatic Alembic utils
If you build custom migration frameworks on top of Alembic:
from waudit_tools.alembic.utils import create_heartbeat, drop_heartbeat
from sqlalchemy.engine import Connection
def my_custom_setup(conn: Connection) -> None:
create_heartbeat(conn, schema="public")
# ... your logic
Why REPLICA IDENTITY FULL?
Debezium needs "before" values for UPDATE and DELETE events. PostgreSQL only sends the changed columns by default. REPLICA IDENTITY FULL forces Postgres to include the complete old row in the WAL, enabling full change-data-capture audit trails.
Architecture
waudit_tools/
├── alembic/
│ ├── setup.py # WauditSetupOp, WauditSetupFromBaseOp, WauditSetupTableOp
│ ├── remove.py # WauditRemoveOp, WauditRemoveFromBaseOp, WauditRemoveTableOp
│ ├── utils.py # create_heartbeat, drop_heartbeat
│ └── __init__.py # side-effect registration
├── sql/
│ ├── identity.py # generate_identity_sql, apply_identity_to_tables
│ └── heartbeat.py # generate_heartbeat_sql, generate_drop_heartbeat_sql
└── sqlalchemy/
└── mixins/
├── str_mixin.py # WAuditStrMixin
└── uuid_mixin.py # WAuditUUIDMixin
Development
This project uses uv for dependency management and builds.
git clone https://github.com/Mac3g0d/waudit-tools.git
cd waudit-tools
# Install with dev dependencies (uv will use the uv.lock file)
uv sync --group dev
# Run tests
uv run pytest
# Lint & typecheck
uv run ruff check src tests
uv run mypy src
# Build wheel + sdist
uv build
Quality gates:
- ruff:
select = ["ALL"] - mypy: strict mode
- pytest-cov: 85% minimum (currently 100%)
License
MIT — see LICENSE.
Author
Wootya viktorzhirnov07@gmail.com
Links
Project details
Release history Release notifications | RSS feed
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 waudit_tools-0.1.1.tar.gz.
File metadata
- Download URL: waudit_tools-0.1.1.tar.gz
- Upload date:
- Size: 61.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90fd23e7f95c423a6ca961d628130997d474ac51708b4607f4215b7a763a1755
|
|
| MD5 |
78f07cb5430af216abd4535a3b08a332
|
|
| BLAKE2b-256 |
40978d4ee3249198070c1a31c6b5f1357cd37041bcef6f6ab04ca8e3a8ac1baa
|
File details
Details for the file waudit_tools-0.1.1-py3-none-any.whl.
File metadata
- Download URL: waudit_tools-0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89817d59b26c95e9f29f86f4270491bf8c4e76d4c57fd9ace5c509e924ba8dbd
|
|
| MD5 |
377b026190bfb95733cbf81f35626a36
|
|
| BLAKE2b-256 |
6d8a90af7c7dab53ef2bff46be96e816f33d1eab76f53f16bdb116ea4b83b032
|