From 36b59ac853faf357e63e579f90330b9281a9f283 Mon Sep 17 00:00:00 2001 From: MingxuanGame Date: Sun, 10 Aug 2025 04:30:06 +0000 Subject: [PATCH] fix(database): fix pydantic warnings --- app/database/beatmap.py | 22 ++++-------- app/database/beatmapset.py | 64 ++++++++++++----------------------- app/models/multiplayer_hub.py | 4 +-- app/models/user.py | 7 ++-- 4 files changed, 33 insertions(+), 64 deletions(-) diff --git a/app/database/beatmap.py b/app/database/beatmap.py index 192ac71..096e9b9 100644 --- a/app/database/beatmap.py +++ b/app/database/beatmap.py @@ -7,7 +7,7 @@ from app.models.score import MODE_TO_INT, GameMode from .beatmap_playcounts import BeatmapPlaycounts from .beatmapset import Beatmapset, BeatmapsetResp -from sqlalchemy import DECIMAL, Column, DateTime +from sqlalchemy import Column, DateTime from sqlmodel import VARCHAR, Field, Relationship, SQLModel, col, func, select from sqlmodel.ext.asyncio.session import AsyncSession @@ -27,9 +27,7 @@ class BeatmapBase(SQLModel): url: str mode: GameMode beatmapset_id: int = Field(foreign_key="beatmapsets.id", index=True) - difficulty_rating: float = Field( - default=0.0, sa_column=Column(DECIMAL(precision=10, scale=6)) - ) + difficulty_rating: float = Field(default=0.0) total_length: int user_id: int version: str @@ -41,17 +39,11 @@ class BeatmapBase(SQLModel): # TODO: failtimes, owners # BeatmapExtended - ar: float = Field(default=0.0, sa_column=Column(DECIMAL(precision=10, scale=2))) - cs: float = Field(default=0.0, sa_column=Column(DECIMAL(precision=10, scale=2))) - drain: float = Field( - default=0.0, - sa_column=Column(DECIMAL(precision=10, scale=2)), - ) # hp - accuracy: float = Field( - default=0.0, - sa_column=Column(DECIMAL(precision=10, scale=2)), - ) # od - bpm: float = Field(default=0.0, sa_column=Column(DECIMAL(precision=10, scale=2))) + ar: float = Field(default=0.0) + cs: float = Field(default=0.0) + drain: float = Field(default=0.0) # hp + accuracy: float = Field(default=0.0) # od + bpm: float = Field(default=0.0) count_circles: int = Field(default=0) count_sliders: int = Field(default=0) count_spinners: int = Field(default=0) diff --git a/app/database/beatmapset.py b/app/database/beatmapset.py index 8a95017..df7bc57 100644 --- a/app/database/beatmapset.py +++ b/app/database/beatmapset.py @@ -1,13 +1,13 @@ from datetime import datetime -from typing import TYPE_CHECKING, TypedDict, cast +from typing import TYPE_CHECKING, NotRequired, TypedDict from app.models.beatmap import BeatmapRankStatus, Genre, Language from app.models.score import GameMode from .lazer_user import BASE_INCLUDES, User, UserResp -from pydantic import BaseModel, model_serializer -from sqlalchemy import DECIMAL, JSON, Column, DateTime, Text +from pydantic import BaseModel +from sqlalchemy import JSON, Column, DateTime, Text from sqlalchemy.ext.asyncio import AsyncAttrs from sqlmodel import Field, Relationship, SQLModel, col, func, select from sqlmodel.ext.asyncio.session import AsyncSession @@ -19,41 +19,19 @@ if TYPE_CHECKING: from .favourite_beatmapset import FavouriteBeatmapset -class BeatmapCovers(SQLModel): - cover: str - card: str - list: str - slimcover: str - cover_2_x: str | None = Field(default=None, alias="cover@2x") - card_2_x: str | None = Field(default=None, alias="card@2x") - list_2_x: str | None = Field(default=None, alias="list@2x") - slimcover_2_x: str | None = Field(default=None, alias="slimcover@2x") - - @model_serializer - def _(self) -> dict[str, str | None]: - self = cast(dict[str, str | None] | BeatmapCovers, self) - if isinstance(self, dict): - return { - "cover": self["cover"], - "card": self["card"], - "list": self["list"], - "slimcover": self["slimcover"], - "cover@2x": self.get("cover@2x"), - "card@2x": self.get("card@2x"), - "list@2x": self.get("list@2x"), - "slimcover@2x": self.get("slimcover@2x"), - } - else: - return { - "cover": self.cover, - "card": self.card, - "list": self.list, - "slimcover": self.slimcover, - "cover@2x": self.cover_2_x, - "card@2x": self.card_2_x, - "list@2x": self.list_2_x, - "slimcover@2x": self.slimcover_2_x, - } +BeatmapCovers = TypedDict( + "BeatmapCovers", + { + "cover": str, + "card": str, + "list": str, + "slimcover": str, + "cover@2x": NotRequired[str | None], + "card@2x": NotRequired[str | None], + "list@2x": NotRequired[str | None], + "slimcover@2x": NotRequired[str | None], + }, +) class BeatmapHype(BaseModel): @@ -75,12 +53,12 @@ class BeatmapNomination(TypedDict): beatmapset_id: int reset: bool user_id: int - rulesets: list[GameMode] | None + rulesets: NotRequired[list[GameMode] | None] -class BeatmapDescription(SQLModel): - bbcode: str | None = None - description: str | None = None +class BeatmapDescription(TypedDict): + bbcode: NotRequired[str | None] + description: NotRequired[str | None] class BeatmapTranslationText(BaseModel): @@ -122,7 +100,7 @@ class BeatmapsetBase(SQLModel): track_id: int | None = Field(default=None) # feature artist? # BeatmapsetExtended - bpm: float = Field(default=0.0, sa_column=Column(DECIMAL(10, 2))) + bpm: float = Field(default=0.0) can_be_hyped: bool = Field(default=False) discussion_locked: bool = Field(default=False) last_updated: datetime = Field(sa_column=Column(DateTime)) diff --git a/app/models/multiplayer_hub.py b/app/models/multiplayer_hub.py index 35b94c1..90613de 100644 --- a/app/models/multiplayer_hub.py +++ b/app/models/multiplayer_hub.py @@ -528,9 +528,7 @@ class MultiplayerQueue: item.validate_playlist_item_mods() item.owner_id = user.user_id - item.star_rating = float( - beatmap.difficulty_rating - ) # FIXME: beatmap use decimal + item.star_rating = beatmap.difficulty_rating await Playlist.add_to_db(item, self.room.room_id, session) self.room.playlist.append(item) await self.hub.playlist_added(self.server_room, item) diff --git a/app/models/user.py b/app/models/user.py index 3b522e8..a564238 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -2,6 +2,7 @@ from __future__ import annotations from datetime import datetime from enum import Enum +from typing import NotRequired, TypedDict from .model import UTCBaseModel @@ -83,9 +84,9 @@ class RankHistory(BaseModel): data: list[int] -class Page(BaseModel): - html: str = "" - raw: str = "" +class Page(TypedDict): + html: NotRequired[str] + raw: NotRequired[str] class BeatmapsetType(str, Enum):