hexastack-db
SQLAlchemy 2.0+ persistence layer, generic repositories, Unit of Work, declarative mixins, and Alembic migrations for Hexastack.
1. Overview & Capabilities
hexastack-db provides a robust, decoupled database layer supporting both synchronous and asynchronous workflows:
- Generic Repositories:
SqlAlchemyRepository[T, ID]andAsyncSqlAlchemyRepository[T, ID]implementingRepository[E, ID]andAsyncRepository[E, ID]. - Unit of Work:
SqlAlchemyUnitOfWorkandAsyncSqlAlchemyUnitOfWorkproviding contextual transaction boundaries (commit(),rollback()). - Declarative Base & Mixins:
HexastackBase: SharedDeclarativeBasefor unified metadata management across applications and migration autogen.UuidPrimaryKeyMixin: Portable Python-sideuuid4()stored as a 36-character string primary key.TimestampMixin: Automatic UTCcreated_atandupdated_attimestamps.
- Alembic Migration Engine: Programmatic migration execution (
upgrade,downgrade,revision,current,history,stamp) and CLI integration without requiring manualalembic.iniauthoring. - Auto Table Creation: Schema discovery and
create_all()execution on bootstrap viaregister_metadata().
2. Package Anatomy & Key Components
hexastack_db/
├── domain/ # DatabaseError, EntityNotFoundError, UniqueConstraintViolationError
├── adapters/ # SqlAlchemyRepository, AsyncSqlAlchemyRepository, SqlAlchemyUnitOfWork, AsyncSqlAlchemyUnitOfWork
└── infra/
├── bootstrap.py # DatabaseBootstrapper (order=15)
├── config.py # HexastackDatabaseConfig
├── engine.py # Engine and sessionmaker factory functions
├── mixins.py # HexastackBase, UuidPrimaryKeyMixin, TimestampMixin
├── migrations.py# Alembic migration helpers
└── registries/ # metadata.py (register_metadata, get_registered_metadata)
Key Exports
| Category | Exports |
|---|---|
| Bootstrap | DatabaseBootstrapper (order=15), HexastackDatabaseConfig |
| Migrations | init_migrations, get_alembic_config, run_upgrade, run_downgrade, run_revision, run_current, run_history, stamp |
| Mixins & Base | HexastackBase, UuidPrimaryKeyMixin, TimestampMixin |
| Registries | register_metadata, get_registered_metadata, clear_metadata_registry |
| Repositories | SqlAlchemyRepository, AsyncSqlAlchemyRepository |
| Unit of Work | SqlAlchemyUnitOfWork, AsyncSqlAlchemyUnitOfWork |
3. Monorepo & Sibling Relationships
graph TD
subgraph SiblingConsumers ["Sibling Consumers"]
CQRS["hexastack-cqrs (UnitOfWorkMiddleware)"]
FASTAPI["hexastack-fastapi (DbSessionMiddleware)"]
CLI["hexastack (hexastack db <cmd>)"]
end
subgraph DatabasePackage ["hexastack-db"]
BOOT["DatabaseBootstrapper (order=15)"]
UOW["SqlAlchemyUnitOfWork / AsyncSqlAlchemyUnitOfWork"]
ENG["Engine & sessionmaker"]
MIGR["Alembic Migration Engine"]
end
subgraph CoreContracts ["hexastack-core"]
UOW_PORT["UnitOfWorkPort"]
REPO_PORT["RepositoryPort"]
end
BOOT --> UOW
BOOT --> ENG
UOW -->|implements| UOW_PORT
CQRS -. consumes UnitOfWorkPort from DI .-> UOW
FASTAPI -. consumes sessionmaker from DI .-> ENG
CLI -. invokes migration helpers .-> MIGR
Explicit Dependencies (Direct)
hexastack-core: Core ports (UnitOfWorkPort,Repository), exception types, and DI container.sqlalchemy>=2.0.38: Core ORM and SQL toolkit.
Implied / Behavioral Relationships (DI-Mediated)
- Unit of Work Binding: Binds
UnitOfWorkPortinto the DI container atorder=15(before CQRSorder=20), allowingUnitOfWorkMiddlewareto manage transactions automatically. - Session Injection: Injects
sessionmaker/async_sessionmakerinto DI, whichhexastack-fastapiresolves inDbSessionMiddlewarewithout requiring a direct package dependency. - Migration CLI Integration: The
hexastackumbrella package exposes CLI subcommands (hexastack db init/upgrade/revision/...) backed byhexastack_db.infra.migrations.
Optional Integrations (Extras)
[sqlite]: Installsaiosqlite>=0.20.0for async SQLite support.[postgresql]: Installsasyncpg>=0.30.0andpsycopg[binary]>=3.2.0.[pgvector]: Installspgvector>=0.3.0and PostgreSQL drivers for VectorStorePort support.[migrations]: Installsalembic>=1.13.0for migration commands and autogeneration.[all]: Installs all drivers, pgvector, and Alembic.
4. Installation
# Standalone install with SQLite async support
pip install "hexastack-db[sqlite]"
# Standalone with PostgreSQL and Alembic migrations
pip install "hexastack-db[postgresql,migrations]"
# With PostgreSQL vector search (pgvector)
pip install "hexastack-db[pgvector]"
# Via umbrella package
pip install "hexastack[db]"
5. Configuration Reference
[hexastack.db]
# Global Settings
url = "sqlite:///app.db" # "postgresql+asyncpg://user:pass@localhost:5432/dbname"
async_mode = false # Set to true for async engine & sessions
auto_create_tables = false # Runs create_all() on registered metadata at bootstrap
echo = false # Enables raw SQLAlchemy SQL logging
pool_size = 5
max_overflow = 10
pool_timeout = 30
pool_recycle = 1800
# SQLite-Specific Dialect Settings
[hexastack.db.sqlite]
foreign_keys = true # PRAGMA foreign_keys = ON
journal_mode = "WAL" # PRAGMA journal_mode = WAL
busy_timeout_ms = 5000 # PRAGMA busy_timeout = 5000
synchronous = "NORMAL"
# PostgreSQL-Specific Dialect Settings
[hexastack.db.postgres]
search_path = "public"
ssl_mode = "require"
server_side_cursors = false
# PostgreSQL pgvector Configuration
[hexastack.db.vector]
enabled = false # Auto-binds VectorStorePort in DI container
table_name = "hexastack_vectors"
dimension = 1536
distance_strategy = "cosine" # "cosine", "l2", "inner_product"
index_type = "hnsw" # "hnsw", "ivfflat", "none"
m = 16
ef_construction = 64
6. Quickstart Example
from sqlalchemy.orm import Mapped, mapped_column
from hexastack_core.infra.bootstrap import bootstrap
from hexastack_core.ports.unit_of_work import UnitOfWorkPort
from hexastack_db.infra.mixins import HexastackBase, UuidPrimaryKeyMixin, TimestampMixin
from hexastack_db.infra.registries.metadata import register_metadata
from hexastack_db.adapters.repository import SqlAlchemyRepository
# 1. Define Model
class UserRecord(UuidPrimaryKeyMixin, TimestampMixin, HexastackBase):
__tablename__ = "users"
email: Mapped[str] = mapped_column(unique=True)
register_metadata(HexastackBase.metadata)
# 2. Bootstrap with auto-table creation
runtime = bootstrap(
config_overrides={
"db": {
"url": "sqlite:///:memory:",
"auto_create_tables": True,
}
}
)
# 3. Use Unit of Work and Repository
uow = runtime.container.get(UnitOfWorkPort)
with uow:
repo = SqlAlchemyRepository(session=uow.session, model_cls=UserRecord)
user = UserRecord(email="alice@hexastack.dev")
repo.add(user)
uow.commit()
print(f"Created user {user.id} at {user.created_at}")
Metadata
Release files for hexastack-db 0.4.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 | |
|---|---|---|---|
| hexastack_db-0.4.0.tar.gz | 22.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hexastack_db-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 53.1 kB
Release files / hexastack_db-0.4.0.tar.gz
| Download URL | hexastack_db-0.4.0.tar.gz |
|---|---|
| Size | 22.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c47cb512c33e5b7a1a6c965d14af304141d76784c484e45a65d9bc3ae30a9d6e
|
|
BLAKE2b-256 checksum How to use checksums |
c4d6c3b17ef6602e6e4cbb1a127cba7506bdcabdac0e0fe5de4a142c086c1127
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / hexastack_db-0.4.0-py3-none-any.whl
| Download URL | hexastack_db-0.4.0-py3-none-any.whl |
|---|---|
| Size | 30.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
261098bf5cfe0df4448b5f603c4ee4dca736acada2b2c459f861f5a3d0268744
|
|
BLAKE2b-256 checksum How to use checksums |
7eaf08910e0c9a7c40443874f4c74ba71351534fbedd892197d19071c1e418fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|