database.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. """
  2. Database configuration and session management using SQLAlchemy async.
  3. """
  4. from typing import AsyncGenerator
  5. from sqlalchemy import MetaData
  6. from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
  7. from sqlalchemy.ext.declarative import declarative_base
  8. from sqlalchemy.orm import sessionmaker
  9. from app.config import settings
  10. # Create async engine
  11. engine = create_async_engine(
  12. settings.DATABASE_URL,
  13. echo=settings.DEBUG,
  14. future=True,
  15. )
  16. # Create async session factory
  17. async_session_maker = sessionmaker(
  18. engine,
  19. class_=AsyncSession,
  20. expire_on_commit=False,
  21. autocommit=False,
  22. autoflush=False,
  23. )
  24. # Naming convention for constraints (for Alembic)
  25. convention = {
  26. "ix": "ix_%(column_0_label)s",
  27. "uq": "uq_%(table_name)s_%(column_0_name)s",
  28. "ck": "ck_%(table_name)s_%(constraint_name)s",
  29. "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
  30. "pk": "pk_%(table_name)s",
  31. }
  32. metadata = MetaData(naming_convention=convention)
  33. # Base class for all models
  34. Base = declarative_base(metadata=metadata)
  35. async def get_db() -> AsyncGenerator[AsyncSession, None]:
  36. """
  37. Dependency to get database session.
  38. Usage:
  39. @app.get("/users")
  40. async def get_users(db: AsyncSession = Depends(get_db)):
  41. ...
  42. Yields:
  43. AsyncSession instance
  44. """
  45. async with async_session_maker() as session:
  46. try:
  47. yield session
  48. finally:
  49. await session.close()