Add database schema with SQLAlchemy async + Alembic migrations

Set up PostgreSQL database layer with async SQLAlchemy 2.0 and asyncpg driver.
Implements 6 core tables (games, routes, pokemon, route_encounters, nuzlocke_runs,
encounters) with foreign keys, indexes, and an initial Alembic migration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Julian Tabel
2026-02-05 13:29:34 +01:00
parent a87d2ef523
commit d94364d6ce
19 changed files with 649 additions and 19 deletions

View File

@@ -14,8 +14,8 @@ class Settings(BaseSettings):
# API settings
api_v1_prefix: str = "/api/v1"
# Database settings (for future use)
database_url: str = "sqlite:///./nuzlocke.db"
# Database settings
database_url: str = "postgresql+asyncpg://postgres:postgres@localhost:5432/nuzlocke"
settings = Settings()

View File

@@ -0,0 +1,31 @@
from collections.abc import AsyncGenerator
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.orm import DeclarativeBase
from app.core.config import settings
def _get_async_url(url: str) -> str:
"""Ensure the database URL uses the asyncpg driver."""
if url.startswith("postgresql://"):
return url.replace("postgresql://", "postgresql+asyncpg://", 1)
return url
engine = create_async_engine(
_get_async_url(settings.database_url),
echo=settings.debug,
pool_pre_ping=True,
)
async_session = async_sessionmaker(engine, expire_on_commit=False)
class Base(DeclarativeBase):
pass
async def get_session() -> AsyncGenerator[AsyncSession]:
async with async_session() as session:
yield session