Skip to main content

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 — Base and 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, StaleVersionError for 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, includes factory-boy) — example PlanFactory for 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

  1. Point Alembic at the same metadata as your app: target_metadata = Base.metadata (import Base from fast_database).
  2. Ensure env.py loads all model modules so every table is registered on Base.metadata before 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

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)

Source distribution for fastx-database 1.9.0
File Size Uploaded
fastx_database-1.9.0.tar.gz 151.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastx-database 1.9.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

1.9.0 This release

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page