Shared SQLAlchemy ORM models plus IRepository and concrete repos for FastMVC apps.
Project description
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
Project details
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 fastx_database-1.7.0.tar.gz.
File metadata
- Download URL: fastx_database-1.7.0.tar.gz
- Upload date:
- Size: 131.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31c5a3415ab689a5d3d962b3986b0abee49e7122b431031d8b2e7948953e58c1
|
|
| MD5 |
c633201e9d038874815f6f42724e5b1c
|
|
| BLAKE2b-256 |
a746019bf029443ec5b85a0fdfe9e0878aaba68bf20fb3d0cfe8240c46ff4258
|
File details
Details for the file fastx_database-1.7.0-py3-none-any.whl.
File metadata
- Download URL: fastx_database-1.7.0-py3-none-any.whl
- Upload date:
- Size: 221.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c08db5573a7e9b1aa3b035a7c26bf73ec4cd4875203f38f9083e8d9b97fc6ad0
|
|
| MD5 |
30c06be379b1d85efbffd729e88a47ed
|
|
| BLAKE2b-256 |
603dfb13a8a5c12f5452dd9ccedaf71177f443e37d31ce2f25132bbb894b6714
|