Add [database]: add base database models & logic

This commit is contained in:
Kirill Samoylenkov 2025-10-27 19:38:09 +05:00
parent 35eed1e193
commit 839fab48f4
5 changed files with 158 additions and 9 deletions

View file

@ -4,7 +4,7 @@ __all__ = ["start_bot"]
from aiogram import Bot, Dispatcher
from loguru import logger as loguru_logger
from redis.asyncio.client import Redis
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from .handlers import include_routers, registry
from .middlewares import connect_middlewares
@ -14,7 +14,7 @@ from .middlewares import connect_middlewares
async def start_bot(
bot_token: str,
redis_client: Redis,
database_session: AsyncSession,
database_session: async_sessionmaker[AsyncSession],
) -> None:
"""
Start Telegram bot.

View file

@ -1,4 +1,4 @@
__all__ = ["session"]
__all__ = ["create_session", "create_db", "drop_db"]
from .session import session
from .session import create_db, create_session, drop_db

View file

@ -1 +1,107 @@
# TODO: Add database models.
from sqlalchemy import DateTime, ForeignKey, Integer, String, func
from sqlalchemy.orm import (
DeclarativeBase,
Mapped,
mapped_column,
relationship,
)
class Base(DeclarativeBase):
updated: Mapped[DateTime] = mapped_column(
DateTime,
default=func.now(),
onupdate=func.now(),
nullable=False,
)
created: Mapped[DateTime] = mapped_column(
DateTime,
default=func.now(),
nullable=False,
)
class UniversityMember(Base):
__tablename__ = "university_members"
id: Mapped[int] = mapped_column(
Integer,
primary_key=True,
autoincrement=True,
)
name: Mapped[str] = mapped_column(
String(128),
nullable=False,
)
tg_users = relationship(
"TelegramUser",
back_populates="university_member",
cascade="all, delete-orphan",
)
__mapper_args__ = {
"polymorphic_identity": "university_member",
"polymorphic_on": "type",
}
type: Mapped[str] = mapped_column(String(50))
class Student(UniversityMember):
__tablename__ = "students"
id: Mapped[int] = mapped_column(
Integer,
ForeignKey("university_members.id"),
primary_key=True,
)
student_id: Mapped[int] = mapped_column(
Integer,
unique=True,
nullable=False,
)
group_id: Mapped[int] = mapped_column(
Integer,
nullable=True,
)
__mapper_args__ = {
"polymorphic_identity": "student",
}
class TelegramUser(Base):
__tablename__ = "telegram_users"
id: Mapped[int] = mapped_column(
Integer,
primary_key=True,
autoincrement=False,
)
username: Mapped[str] = mapped_column(
String(64),
nullable=True,
)
lang: Mapped[str] = mapped_column(
String(2),
default="ru",
nullable=False,
)
university_member_id: Mapped[int] = mapped_column(
Integer,
ForeignKey("university_members.id"),
nullable=True,
)
university_member = relationship(
"UniversityMember",
back_populates="tg_users",
)

View file

@ -1,4 +1,40 @@
from sqlalchemy.ext.asyncio import AsyncSession
# from loguru import logger as loguru_logger
from sqlalchemy.ext.asyncio import (
AsyncEngine,
AsyncSession,
async_sessionmaker,
create_async_engine,
)
# TODO: Add database session.
session: AsyncSession = ...
from .models import Base
engine: AsyncEngine
def create_session(
url: str, engine_echo: bool = True
) -> async_sessionmaker[AsyncSession]:
global engine
engine = create_async_engine(url=url, echo=engine_echo)
session = async_sessionmaker(
bind=engine,
class_=AsyncSession,
expire_on_commit=False,
)
return session
async def create_db():
global engine
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
async def drop_db():
global engine
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)

View file

@ -2,7 +2,7 @@ import asyncio
from bot import start_bot
from config import configure_logger, settings
from database import session
from database import create_db, create_session
from redis_client import client
@ -17,6 +17,13 @@ def main() -> None:
listen_logging=settings.listen_logging,
)
session = create_session(
url=settings.database_url, engine_echo=True
)
# FIXME: Add argument for create/drop db.
asyncio.run(create_db())
asyncio.run(
start_bot(
bot_token=settings.bot_token,