bifroest/app/core/database.py
2026-10-27 08:34:17 +01:00

42 lines
1.3 KiB
Python

"""SQLAlchemy-Basis, Engine und Sitzungen."""
from collections.abc import Iterator
from contextlib import contextmanager
from datetime import UTC, datetime
from sqlalchemy import DateTime, MetaData, create_engine
from sqlalchemy.engine import Engine
from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker
# Einheitliche Namen für Constraints, damit Alembic-Migrationen stabil bleiben
NAMING = {
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
class Base(DeclarativeBase):
metadata = MetaData(naming_convention=NAMING)
type_annotation_map = {datetime: DateTime(timezone=True)}
def now() -> datetime:
return datetime.now(UTC)
class Database:
def __init__(self, url: str):
self.engine: Engine = create_engine(url, pool_pre_ping=True)
self.sessions = sessionmaker(self.engine, expire_on_commit=False)
@contextmanager
def session(self) -> Iterator[Session]:
"""Eine Transaktion: commit am Ende, rollback bei Fehler."""
with self.sessions() as session, session.begin():
yield session
def dispose(self) -> None:
self.engine.dispose()