fast-database
Shared SQLAlchemy ORM models for FastMVC applications: one declarative Base, table name constants, and models for users/auth, organizations, subscriptions, payments, commerce (cart/orders/shipments), webhooks, notifications, LLM conversation threads, per-user encrypted LLM provider API keys (BYOK), user messaging (chats, messages, read receipts, notification delivery), personal ledger / Pure.cam–aligned tables, and audit logs.
Operational / production patterns baked into the schema include: idempotency (IdempotencyRecord), transactional outbox (OutboxEvent), one-time tokens (UserOneTimeToken), login attempt history (UserLoginEvent), consent (ConsentRecord), plus SystemSetting (runtime toggles), UserMfaFactor (MFA enrollment), DataExportRequest (GDPR-style exports), SecurityEvent (SIEM-friendly signals), and UsageCounter (quota / metering buckets).
The same wheel also ships fast_database.repositories: IRepository, FilterOperator, and concrete repository classes for the tables above (same import paths as before).
Python: 3.10+ · Dependencies: sqlalchemy>=2,<3, loguru, cachetools
Import packages: fast_database, fast_database.repositories
PyPI distribution name: fast-database (hyphenated)
Layout
fast_database.models—Baseand all table classes.fast_database.constants.db.table—Table— centralized string names for__tablename__.fast_database.mixins—TimestampMixin,UUIDPrimaryKeyMixin,SoftDeleteMixin,OrganizationScopedMixin,TenantIdMixin,OptimisticLockMixin,AuditActorMixin.fast_database.optimistic_lock—assert_version_matches,expected_version,StaleVersionErrorfor service-layer checks.fast_database.soft_delete—select_active,where_not_deleted,mark_soft_deleted,restore_soft_deleted,filter_active.fast_database.factories(optional[dev]extra, includesfactory-boy) — examplePlanFactoryfor tests.fast_database.repositories—FilterOperator,IRepository, and per-entity repositories (e.g.from fast_database.repositories.user import UserRepository).
Mixins (new tables)
from sqlalchemy import Column, String
from fast_database import Base, TimestampMixin, UUIDPrimaryKeyMixin, SoftDeleteMixin
class Widget(Base, UUIDPrimaryKeyMixin, TimestampMixin, SoftDeleteMixin):
__tablename__ = "widgets"
label = Column(String(255), nullable=False)
Tenant-scoped rows (composite indexes)
Use OrganizationScopedMixin (organization_id → organizations.id) or TenantIdMixin (generic tenant_id without FK). Add a composite index for common filters:
from sqlalchemy import Column, Index, Integer, String
from fast_database import Base, OrganizationScopedMixin
class InvoiceLine(Base, OrganizationScopedMixin):
__tablename__ = "invoice_lines"
__table_args__ = (Index("ix_invline_org_external", "organization_id", "external_ref"),)
id = Column(Integer, primary_key=True)
external_ref = Column(String(64), nullable=False)
Optimistic locking
Add OptimisticLockMixin and map version with :func:sqlalchemy.orm.declared_attr (see docstring on the mixin). Use assert_version_matches(instance, client_version) before applying updates from the API.
Audit actor columns
AuditActorMixin adds nullable created_by_id / updated_by_id FKs to user.id (set from the current user in services).
factory_boy (tests)
pip install 'fast-database[dev]'
from fast_database.factories import PlanFactory
# Bind PlanFactory._meta.sqlalchemy_session to your test session, then:
plan = PlanFactory()
Alembic autogenerate
- Point Alembic at the same metadata as your app:
target_metadata = Base.metadata(importBasefromfast_database). - Ensure
env.pyloads all model modules so every table is registered onBase.metadatabefore autogenerate runs (otherwise Alembic will propose dropping “unknown” tables).
Example fragment for migrations/env.py (adjust imports to your project layout):
# Load ORM models so Base.metadata is complete before autogenerate.
import fast_database.models # noqa: F401 — registers all tables on Base
from fast_database.models import Base
target_metadata = Base.metadata
# In run_migrations_online(), pass target_metadata to context.configure(
# ...
# target_metadata=target_metadata,
# compare_type=True,
# compare_server_default=True,
# )
Then:
alembic revision --autogenerate -m "describe change"
alembic upgrade head
Review autogenerated diffs carefully (renames are not always detected; constraints may need hand edits).
Install
pip install -e ./fast_database
Or from PyPI (when published):
pip install fast-database
Pair with fast_db so your app’s engine uses the same metadata for Alembic migrations.
For tests with factory_boy examples: pip install 'fast-database[dev]'.
Related packages
fast_db— engine and sessions.- Monorepo: ../README.md.
Tooling
See CONTRIBUTING.md, Makefile, and PUBLISHING.md.
Documentation
| Document | Purpose |
|---|---|
| CONTRIBUTING.md | Dev setup, tests, monorepo sync |
| PUBLISHING.md | PyPI and releases |
| SECURITY.md | Reporting vulnerabilities |
| CHANGELOG.md | Version history |
Monorepo: ../README.md · Coverage: ../docs/COVERAGE.md
Metadata
Release files for fastx-database 1.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastx_database-1.9.0.tar.gz | 151.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastx_database-1.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 395.7 kB
Release files / fastx_database-1.9.0.tar.gz
| Download URL | fastx_database-1.9.0.tar.gz |
|---|---|
| Size | 151.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1d3ca3203cb26ad15a5e42f97f97bb072fb9bf0b7ed34815c3ab8e8fdc743b0
|
|
BLAKE2b-256 checksum How to use checksums |
fa9908947356c9d7ff062404ecbee6fc1819ae31dca654717b90f8b2a6fb1771
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / fastx_database-1.9.0-py3-none-any.whl
| Download URL | fastx_database-1.9.0-py3-none-any.whl |
|---|---|
| Size | 244.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b1124238228ea0a48e6c15adb107d1a0677179d47fbc704d261b441ed0a25a68
|
|
BLAKE2b-256 checksum How to use checksums |
549be8d21f75dfb7b9fff7ea4351cbb7fa8acd2c73129b4a06d8a4ec715024c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|