40a940304b
- Create enhanced health endpoints with /health and /health/db - Add comprehensive docstrings to all API endpoints - Add Pydantic response models with Field descriptions - Create apps/api/README.md with setup guide - Create ADR-001 for session auth decision - Create ADR-002 for async SQLAlchemy decision - Quality gates: Python syntax OK, TypeScript OK
1.9 KiB
1.9 KiB
ADR-002: Async SQLAlchemy with PostgreSQL
Status
Accepted
Context
We need to choose an ORM and database for the application. The application will handle concurrent requests and potentially long-running operations (git operations, Docker commands).
Requirements
- Support concurrent API requests without blocking
- Handle async operations (database queries + subprocess calls)
- Type safety and autocompletion
- Migration support
- Good Python ecosystem support
Decision
We will use SQLAlchemy 2.0 with async PostgreSQL via asyncpg.
Implementation
- SQLAlchemy 2.0 with
AsyncSessionand declarative models - PostgreSQL as the primary database
- asyncpg as the async driver
- Alembic for database migrations
Consequences
Positive
- Non-blocking I/O: Database queries don't block the event loop
- Scalability: Can handle many concurrent connections
- Type safety: SQLAlchemy 2.0 has excellent type hint support
- Ecosystem: Large community, extensive documentation
- Flexibility: Can fall back to sync operations for complex migrations
Negative
- Complexity: Async SQLAlchemy has a steeper learning curve
- Debugging: Harder to debug async code
- Migration limitations: Some Alembic operations require sync connections
- Connection pool: Requires careful configuration
Alternatives Considered
Prisma ORM
- Pros: Modern, type-safe, auto-generated client
- Cons: Less mature Python support, custom query language
- Rejected due to less mature ecosystem
Tortoise ORM
- Pros: Built for async, Django-like syntax
- Cons: Smaller community, fewer features
- Rejected in favor of SQLAlchemy's maturity
Sync SQLAlchemy with threading
- Pros: Simpler, well-understood
- Cons: Thread overhead, harder to integrate with async code
- Rejected in favor of native async support
Date
2026-05-17
Participants
- Development Team