refactor(scores): rename models of score to match with filename

This commit is contained in:
MingxuanGame
2025-10-04 08:01:38 +00:00
parent 80ba65c746
commit 1163a93053
9 changed files with 103 additions and 97 deletions

View File

@@ -12,7 +12,7 @@ from .beatmapset import (
BeatmapsetResp, BeatmapsetResp,
) )
from .beatmapset_ratings import BeatmapRating from .beatmapset_ratings import BeatmapRating
from .best_scores import PPBestScore from .best_scores import BestScore
from .chat import ( from .chat import (
ChannelType, ChannelType,
ChatChannel, ChatChannel,
@@ -56,7 +56,7 @@ from .statistics import (
UserStatisticsResp, UserStatisticsResp,
) )
from .team import Team, TeamMember, TeamRequest from .team import Team, TeamMember, TeamRequest
from .total_score_best_scores import BestScore from .total_score_best_scores import TotalScoreBestScore
from .user import ( from .user import (
MeResp, MeResp,
User, User,
@@ -105,7 +105,6 @@ __all__ = [
"Notification", "Notification",
"OAuthClient", "OAuthClient",
"OAuthToken", "OAuthToken",
"PPBestScore",
"PasswordReset", "PasswordReset",
"Playlist", "Playlist",
"PlaylistAggregateScore", "PlaylistAggregateScore",
@@ -131,6 +130,7 @@ __all__ = [
"Team", "Team",
"TeamMember", "TeamMember",
"TeamRequest", "TeamRequest",
"TotalScoreBestScore",
"TotpKeys", "TotpKeys",
"TrustedDevice", "TrustedDevice",
"TrustedDeviceResp", "TrustedDeviceResp",

View File

@@ -22,7 +22,7 @@ if TYPE_CHECKING:
from .score import Score from .score import Score
class PPBestScore(SQLModel, table=True): class BestScore(SQLModel, table=True):
__tablename__: str = "best_scores" __tablename__: str = "best_scores"
user_id: int = Field(sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True)) user_id: int = Field(sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True))
score_id: int = Field(sa_column=Column(BigInteger, ForeignKey("scores.id"), primary_key=True)) score_id: int = Field(sa_column=Column(BigInteger, ForeignKey("scores.id"), primary_key=True))

View File

@@ -38,7 +38,7 @@ from app.utils import utcnow
from .beatmap import Beatmap, BeatmapResp from .beatmap import Beatmap, BeatmapResp
from .beatmapset import BeatmapsetResp from .beatmapset import BeatmapsetResp
from .best_scores import PPBestScore from .best_scores import BestScore
from .counts import MonthlyPlaycounts from .counts import MonthlyPlaycounts
from .events import Event, EventType from .events import Event, EventType
from .playlist_best_score import PlaylistBestScore from .playlist_best_score import PlaylistBestScore
@@ -47,7 +47,7 @@ from .relationship import (
RelationshipType, RelationshipType,
) )
from .score_token import ScoreToken from .score_token import ScoreToken
from .total_score_best_scores import BestScore from .total_score_best_scores import TotalScoreBestScore
from .user import User, UserResp from .user import User, UserResp
from pydantic import BaseModel, field_serializer, field_validator from pydantic import BaseModel, field_serializer, field_validator
@@ -195,13 +195,13 @@ class Score(ScoreBase, table=True):
# optional # optional
beatmap: Mapped[Beatmap] = Relationship() beatmap: Mapped[Beatmap] = Relationship()
user: Mapped[User] = Relationship(sa_relationship_kwargs={"lazy": "joined"}) user: Mapped[User] = Relationship(sa_relationship_kwargs={"lazy": "joined"})
best_score: Mapped[BestScore | None] = Relationship( best_score: Mapped[TotalScoreBestScore | None] = Relationship(
back_populates="score", back_populates="score",
sa_relationship_kwargs={ sa_relationship_kwargs={
"cascade": "all, delete-orphan", "cascade": "all, delete-orphan",
}, },
) )
ranked_score: Mapped[PPBestScore | None] = Relationship( ranked_score: Mapped[BestScore | None] = Relationship(
back_populates="score", back_populates="score",
sa_relationship_kwargs={ sa_relationship_kwargs={
"cascade": "all, delete-orphan", "cascade": "all, delete-orphan",
@@ -481,10 +481,10 @@ class ScoreAround(SQLModel):
async def get_best_id(session: AsyncSession, score_id: int) -> int | None: async def get_best_id(session: AsyncSession, score_id: int) -> int | None:
rownum = ( rownum = (
func.row_number() func.row_number()
.over(partition_by=(col(PPBestScore.user_id), col(PPBestScore.gamemode)), order_by=col(PPBestScore.pp).desc()) .over(partition_by=(col(BestScore.user_id), col(BestScore.gamemode)), order_by=col(BestScore.pp).desc())
.label("rn") .label("rn")
) )
subq = select(PPBestScore, rownum).subquery() subq = select(BestScore, rownum).subquery()
stmt = select(subq.c.rn).where(subq.c.score_id == score_id) stmt = select(subq.c.rn).where(subq.c.score_id == score_id)
result = await session.exec(stmt) result = await session.exec(stmt)
return result.one_or_none() return result.one_or_none()
@@ -498,8 +498,8 @@ async def _score_where(
user: User | None = None, user: User | None = None,
) -> list[ColumnElement[bool] | TextClause] | None: ) -> list[ColumnElement[bool] | TextClause] | None:
wheres: list[ColumnElement[bool] | TextClause] = [ wheres: list[ColumnElement[bool] | TextClause] = [
col(BestScore.beatmap_id) == beatmap, col(TotalScoreBestScore.beatmap_id) == beatmap,
col(BestScore.gamemode) == mode, col(TotalScoreBestScore.gamemode) == mode,
] ]
if type == LeaderboardType.FRIENDS: if type == LeaderboardType.FRIENDS:
@@ -512,19 +512,21 @@ async def _score_where(
) )
.subquery() .subquery()
) )
wheres.append(col(BestScore.user_id).in_(select(subq.c.target_id))) wheres.append(col(TotalScoreBestScore.user_id).in_(select(subq.c.target_id)))
else: else:
return None return None
elif type == LeaderboardType.COUNTRY: elif type == LeaderboardType.COUNTRY:
if user and user.is_supporter: if user and user.is_supporter:
wheres.append(col(BestScore.user).has(col(User.country_code) == user.country_code)) wheres.append(col(TotalScoreBestScore.user).has(col(User.country_code) == user.country_code))
else: else:
return None return None
elif type == LeaderboardType.TEAM and user: elif type == LeaderboardType.TEAM and user:
team_membership = await user.awaitable_attrs.team_membership team_membership = await user.awaitable_attrs.team_membership
if team_membership: if team_membership:
team_id = team_membership.team_id team_id = team_membership.team_id
wheres.append(col(BestScore.user).has(col(User.team_membership).has(TeamMember.team_id == team_id))) wheres.append(
col(TotalScoreBestScore.user).has(col(User.team_membership).has(TeamMember.team_id == team_id))
)
if mods: if mods:
if user and user.is_supporter: if user and user.is_supporter:
wheres.append( wheres.append(
@@ -558,10 +560,10 @@ async def get_leaderboard(
max_score = sys.maxsize max_score = sys.maxsize
while limit > 0: while limit > 0:
query = ( query = (
select(BestScore) select(TotalScoreBestScore)
.where(*wheres, BestScore.total_score < max_score) .where(*wheres, TotalScoreBestScore.total_score < max_score)
.limit(limit) .limit(limit)
.order_by(col(BestScore.total_score).desc()) .order_by(col(TotalScoreBestScore.total_score).desc())
) )
extra_need = 0 extra_need = 0
for s in await session.exec(query): for s in await session.exec(query):
@@ -580,13 +582,13 @@ async def get_leaderboard(
user_score = None user_score = None
if user: if user:
self_query = ( self_query = (
select(BestScore) select(TotalScoreBestScore)
.where(BestScore.user_id == user.id) .where(TotalScoreBestScore.user_id == user.id)
.where( .where(
col(BestScore.beatmap_id) == beatmap, col(TotalScoreBestScore.beatmap_id) == beatmap,
col(BestScore.gamemode) == mode, col(TotalScoreBestScore.gamemode) == mode,
) )
.order_by(col(BestScore.total_score).desc()) .order_by(col(TotalScoreBestScore.total_score).desc())
.limit(1) .limit(1)
) )
if mods: if mods:
@@ -619,14 +621,14 @@ async def get_score_position_by_user(
func.row_number() func.row_number()
.over( .over(
partition_by=( partition_by=(
col(BestScore.beatmap_id), col(TotalScoreBestScore.beatmap_id),
col(BestScore.gamemode), col(TotalScoreBestScore.gamemode),
), ),
order_by=col(BestScore.total_score).desc(), order_by=col(TotalScoreBestScore.total_score).desc(),
) )
.label("row_number") .label("row_number")
) )
subq = select(BestScore, rownum).join(Beatmap).where(*wheres).subquery() subq = select(TotalScoreBestScore, rownum).join(Beatmap).where(*wheres).subquery()
stmt = select(subq.c.row_number).where(subq.c.user_id == user.id) stmt = select(subq.c.row_number).where(subq.c.user_id == user.id)
result = await session.exec(stmt) result = await session.exec(stmt)
s = result.first() s = result.first()
@@ -649,14 +651,14 @@ async def get_score_position_by_id(
func.row_number() func.row_number()
.over( .over(
partition_by=( partition_by=(
col(BestScore.beatmap_id), col(TotalScoreBestScore.beatmap_id),
col(BestScore.gamemode), col(TotalScoreBestScore.gamemode),
), ),
order_by=col(BestScore.total_score).desc(), order_by=col(TotalScoreBestScore.total_score).desc(),
) )
.label("row_number") .label("row_number")
) )
subq = select(BestScore, rownum).join(Beatmap).where(*wheres).subquery() subq = select(TotalScoreBestScore, rownum).join(Beatmap).where(*wheres).subquery()
stmt = select(subq.c.row_number).where(subq.c.score_id == score_id) stmt = select(subq.c.row_number).where(subq.c.score_id == score_id)
result = await session.exec(stmt) result = await session.exec(stmt)
s = result.one_or_none() s = result.one_or_none()
@@ -668,16 +670,16 @@ async def get_user_best_score_in_beatmap(
beatmap: int, beatmap: int,
user: int, user: int,
mode: GameMode | None = None, mode: GameMode | None = None,
) -> BestScore | None: ) -> TotalScoreBestScore | None:
return ( return (
await session.exec( await session.exec(
select(BestScore) select(TotalScoreBestScore)
.where( .where(
BestScore.gamemode == mode if mode is not None else true(), TotalScoreBestScore.gamemode == mode if mode is not None else true(),
BestScore.beatmap_id == beatmap, TotalScoreBestScore.beatmap_id == beatmap,
BestScore.user_id == user, TotalScoreBestScore.user_id == user,
) )
.order_by(col(BestScore.total_score).desc()) .order_by(col(TotalScoreBestScore.total_score).desc())
) )
).first() ).first()
@@ -688,32 +690,32 @@ async def get_user_best_score_with_mod_in_beatmap(
user: int, user: int,
mod: list[str], mod: list[str],
mode: GameMode | None = None, mode: GameMode | None = None,
) -> BestScore | None: ) -> TotalScoreBestScore | None:
return ( return (
await session.exec( await session.exec(
select(BestScore) select(TotalScoreBestScore)
.where( .where(
BestScore.gamemode == mode if mode is not None else True, TotalScoreBestScore.gamemode == mode if mode is not None else True,
BestScore.beatmap_id == beatmap, TotalScoreBestScore.beatmap_id == beatmap,
BestScore.user_id == user, TotalScoreBestScore.user_id == user,
text( text(
"JSON_CONTAINS(total_score_best_scores.mods, :w)" "JSON_CONTAINS(total_score_best_scores.mods, :w)"
" AND JSON_CONTAINS(:w, total_score_best_scores.mods)" " AND JSON_CONTAINS(:w, total_score_best_scores.mods)"
).params(w=json.dumps(mod)), ).params(w=json.dumps(mod)),
) )
.order_by(col(BestScore.total_score).desc()) .order_by(col(TotalScoreBestScore.total_score).desc())
) )
).first() ).first()
async def get_user_first_scores( async def get_user_first_scores(
session: AsyncSession, user_id: int, mode: GameMode, limit: int = 5, offset: int = 0 session: AsyncSession, user_id: int, mode: GameMode, limit: int = 5, offset: int = 0
) -> list[BestScore]: ) -> list[TotalScoreBestScore]:
rownum = ( rownum = (
func.row_number() func.row_number()
.over( .over(
partition_by=(col(BestScore.beatmap_id), col(BestScore.gamemode)), partition_by=(col(TotalScoreBestScore.beatmap_id), col(TotalScoreBestScore.gamemode)),
order_by=col(BestScore.total_score).desc(), order_by=col(TotalScoreBestScore.total_score).desc(),
) )
.label("rn") .label("rn")
) )
@@ -721,11 +723,11 @@ async def get_user_first_scores(
# Step 1: Fetch top score_ids in Python # Step 1: Fetch top score_ids in Python
subq = ( subq = (
select( select(
col(BestScore.score_id).label("score_id"), col(TotalScoreBestScore.score_id).label("score_id"),
col(BestScore.user_id).label("user_id"), col(TotalScoreBestScore.user_id).label("user_id"),
rownum, rownum,
) )
.where(col(BestScore.gamemode) == mode) .where(col(TotalScoreBestScore.gamemode) == mode)
.subquery() .subquery()
) )
@@ -734,7 +736,11 @@ async def get_user_first_scores(
top_ids = await session.exec(top_ids_stmt) top_ids = await session.exec(top_ids_stmt)
top_ids = list(top_ids) top_ids = list(top_ids)
stmt = select(BestScore).where(col(BestScore.score_id).in_(top_ids)).order_by(col(BestScore.total_score).desc()) stmt = (
select(TotalScoreBestScore)
.where(col(TotalScoreBestScore.score_id).in_(top_ids))
.order_by(col(TotalScoreBestScore.total_score).desc())
)
result = await session.exec(stmt) result = await session.exec(stmt)
return list(result.all()) return list(result.all())
@@ -744,18 +750,18 @@ async def get_user_first_score_count(session: AsyncSession, user_id: int, mode:
rownum = ( rownum = (
func.row_number() func.row_number()
.over( .over(
partition_by=(col(BestScore.beatmap_id), col(BestScore.gamemode)), partition_by=(col(TotalScoreBestScore.beatmap_id), col(TotalScoreBestScore.gamemode)),
order_by=col(BestScore.total_score).desc(), order_by=col(TotalScoreBestScore.total_score).desc(),
) )
.label("rn") .label("rn")
) )
subq = ( subq = (
select( select(
col(BestScore.score_id).label("score_id"), col(TotalScoreBestScore.score_id).label("score_id"),
col(BestScore.user_id).label("user_id"), col(TotalScoreBestScore.user_id).label("user_id"),
rownum, rownum,
) )
.where(col(BestScore.gamemode) == mode) .where(col(TotalScoreBestScore.gamemode) == mode)
.subquery() .subquery()
) )
count_stmt = select(func.count()).where(subq.c.rn == 1, subq.c.user_id == user_id) count_stmt = select(func.count()).where(subq.c.rn == 1, subq.c.user_id == user_id)
@@ -769,13 +775,13 @@ async def get_user_best_pp_in_beatmap(
beatmap: int, beatmap: int,
user: int, user: int,
mode: GameMode, mode: GameMode,
) -> PPBestScore | None: ) -> BestScore | None:
return ( return (
await session.exec( await session.exec(
select(PPBestScore).where( select(BestScore).where(
PPBestScore.beatmap_id == beatmap, BestScore.beatmap_id == beatmap,
PPBestScore.user_id == user, BestScore.user_id == user,
PPBestScore.gamemode == mode, BestScore.gamemode == mode,
) )
) )
).first() ).first()
@@ -800,12 +806,12 @@ async def get_user_best_pp(
user: int, user: int,
mode: GameMode, mode: GameMode,
limit: int = 1000, limit: int = 1000,
) -> Sequence[PPBestScore]: ) -> Sequence[BestScore]:
return ( return (
await session.exec( await session.exec(
select(PPBestScore) select(BestScore)
.where(PPBestScore.user_id == user, PPBestScore.gamemode == mode) .where(BestScore.user_id == user, BestScore.gamemode == mode)
.order_by(col(PPBestScore.pp).desc()) .order_by(col(BestScore.pp).desc())
.limit(limit) .limit(limit)
) )
).all() ).all()
@@ -936,7 +942,7 @@ async def _process_score_pp(score: Score, session: AsyncSession, redis: Redis, f
beatmap_id = score.beatmap_id beatmap_id = score.beatmap_id
previous_pp_best = await get_user_best_pp_in_beatmap(session, beatmap_id, user_id, score.gamemode) previous_pp_best = await get_user_best_pp_in_beatmap(session, beatmap_id, user_id, score.gamemode)
if previous_pp_best is None or score.pp > previous_pp_best.pp: if previous_pp_best is None or score.pp > previous_pp_best.pp:
best_score = PPBestScore( best_score = BestScore(
user_id=user_id, user_id=user_id,
score_id=score.id, score_id=score.id,
beatmap_id=beatmap_id, beatmap_id=beatmap_id,
@@ -1010,12 +1016,12 @@ async def _process_score_events(score: Score, session: AsyncSession):
if rank_global == 1: if rank_global == 1:
displaced_score = ( displaced_score = (
await session.exec( await session.exec(
select(BestScore) select(TotalScoreBestScore)
.where( .where(
BestScore.beatmap_id == score.beatmap_id, TotalScoreBestScore.beatmap_id == score.beatmap_id,
BestScore.gamemode == score.gamemode, TotalScoreBestScore.gamemode == score.gamemode,
) )
.order_by(col(BestScore.total_score).desc()) .order_by(col(TotalScoreBestScore.total_score).desc())
.limit(1) .limit(1)
.offset(1) .offset(1)
) )
@@ -1139,7 +1145,7 @@ async def _process_statistics(
# 情况2: 有最佳分数记录但没有该mod组合的记录添加新记录 # 情况2: 有最佳分数记录但没有该mod组合的记录添加新记录
if previous_score_best is None or previous_score_best_mod is None: if previous_score_best is None or previous_score_best_mod is None:
session.add( session.add(
BestScore( TotalScoreBestScore(
user_id=user.id, user_id=user.id,
beatmap_id=score.beatmap_id, beatmap_id=score.beatmap_id,
gamemode=score.gamemode, gamemode=score.gamemode,

View File

@@ -25,7 +25,7 @@ if TYPE_CHECKING:
from .score import Score from .score import Score
class BestScore(SQLModel, table=True): class TotalScoreBestScore(SQLModel, table=True):
__tablename__: str = "total_score_best_scores" __tablename__: str = "total_score_best_scores"
user_id: int = Field(sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True)) user_id: int = Field(sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True))
score_id: int = Field(sa_column=Column(BigInteger, ForeignKey("scores.id"), primary_key=True)) score_id: int = Field(sa_column=Column(BigInteger, ForeignKey("scores.id"), primary_key=True))
@@ -41,7 +41,7 @@ class BestScore(SQLModel, table=True):
user: User = Relationship() user: User = Relationship()
score: "Score" = Relationship( score: "Score" = Relationship(
sa_relationship_kwargs={ sa_relationship_kwargs={
"foreign_keys": "[BestScore.score_id]", "foreign_keys": "[TotalScoreBestScore.score_id]",
"lazy": "joined", "lazy": "joined",
}, },
back_populates="best_score", back_populates="best_score",
@@ -75,7 +75,7 @@ class BestScore(SQLModel, table=True):
await session.exec( await session.exec(
select(func.max(Score.max_combo)).where( select(func.max(Score.max_combo)).where(
Score.user_id == self.user_id, Score.user_id == self.user_id,
col(Score.id).in_(select(BestScore.score_id)), col(Score.id).in_(select(TotalScoreBestScore.score_id)),
Score.gamemode == self.gamemode, Score.gamemode == self.gamemode,
) )
) )

View File

@@ -259,11 +259,11 @@ class UserResp(UserBase):
) -> "UserResp": ) -> "UserResp":
from app.dependencies.database import get_redis from app.dependencies.database import get_redis
from .best_scores import PPBestScore from .best_scores import BestScore
from .favourite_beatmapset import FavouriteBeatmapset from .favourite_beatmapset import FavouriteBeatmapset
from .relationship import Relationship, RelationshipResp, RelationshipType from .relationship import Relationship, RelationshipResp, RelationshipType
from .score import Score, get_user_first_score_count from .score import Score, get_user_first_score_count
from .total_score_best_scores import BestScore from .total_score_best_scores import TotalScoreBestScore
ruleset = ruleset or obj.playmode ruleset = ruleset or obj.playmode
@@ -284,9 +284,9 @@ class UserResp(UserBase):
u.scores_best_count = ( u.scores_best_count = (
await session.exec( await session.exec(
select(func.count()) select(func.count())
.select_from(BestScore) .select_from(TotalScoreBestScore)
.where( .where(
BestScore.user_id == obj.id, TotalScoreBestScore.user_id == obj.id,
) )
.limit(200) .limit(200)
) )
@@ -391,10 +391,10 @@ class UserResp(UserBase):
u.scores_best_count = ( u.scores_best_count = (
await session.exec( await session.exec(
select(func.count()) select(func.count())
.select_from(PPBestScore) .select_from(BestScore)
.where( .where(
PPBestScore.user_id == obj.id, BestScore.user_id == obj.id,
PPBestScore.gamemode == ruleset, BestScore.gamemode == ruleset,
) )
.limit(200) .limit(200)
) )

View File

@@ -1,7 +1,7 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Annotated, Literal from typing import Annotated, Literal
from app.database.best_scores import PPBestScore from app.database.best_scores import BestScore
from app.database.score import Score, get_leaderboard from app.database.score import Score, get_leaderboard
from app.dependencies.database import Database from app.dependencies.database import Database
from app.models.mods import int_to_mods, mod_to_save, mods_to_int from app.models.mods import int_to_mods, mod_to_save, mods_to_int
@@ -79,7 +79,7 @@ async def get_user_best(
.where( .where(
Score.user_id == user if type == "id" or user.isdigit() else col(Score.user).has(username=user), Score.user_id == user if type == "id" or user.isdigit() else col(Score.user).has(username=user),
Score.gamemode == GameMode.from_int_extra(ruleset_id), Score.gamemode == GameMode.from_int_extra(ruleset_id),
exists().where(col(PPBestScore.score_id) == Score.id), exists().where(col(BestScore.score_id) == Score.id),
) )
.order_by(col(Score.pp).desc()) .order_by(col(Score.pp).desc())
.options(joinedload(Score.beatmap)) .options(joinedload(Score.beatmap))

View File

@@ -10,7 +10,7 @@ from app.database import (
User, User,
UserResp, UserResp,
) )
from app.database.best_scores import PPBestScore from app.database.best_scores import BestScore
from app.database.events import Event from app.database.events import Event
from app.database.score import LegacyScoreResp, Score, ScoreResp, get_user_first_scores from app.database.score import LegacyScoreResp, Score, ScoreResp, get_user_first_scores
from app.database.user import SEARCH_INCLUDED from app.database.user import SEARCH_INCLUDED
@@ -392,7 +392,7 @@ async def get_user_scores(
where_clause &= Score.pinned_order > 0 where_clause &= Score.pinned_order > 0
order_by = col(Score.pinned_order).asc() order_by = col(Score.pinned_order).asc()
elif type == "best": elif type == "best":
where_clause &= exists().where(col(PPBestScore.score_id) == Score.id) where_clause &= exists().where(col(BestScore.score_id) == Score.id)
order_by = col(Score.pp).desc() order_by = col(Score.pp).desc()
elif type == "recent": elif type == "recent":
where_clause &= Score.ended_at > utcnow() - timedelta(hours=24) where_clause &= Score.ended_at > utcnow() - timedelta(hours=24)

View File

@@ -4,7 +4,7 @@ import json
from app.calculator import calculate_pp from app.calculator import calculate_pp
from app.config import settings from app.config import settings
from app.database.beatmap import BannedBeatmaps, Beatmap from app.database.beatmap import BannedBeatmaps, Beatmap
from app.database.best_scores import PPBestScore from app.database.best_scores import BestScore
from app.database.score import Score, calculate_user_pp from app.database.score import Score, calculate_user_pp
from app.database.statistics import UserStatistics from app.database.statistics import UserStatistics
from app.dependencies.database import get_redis, with_db from app.dependencies.database import get_redis, with_db
@@ -35,7 +35,7 @@ async def recalculate_banned_beatmap():
unbanned_beatmaps = [b for b in last_banned_beatmaps if b not in current_banned] unbanned_beatmaps = [b for b in last_banned_beatmaps if b not in current_banned]
for i in new_banned_beatmaps: for i in new_banned_beatmaps:
last_banned_beatmaps.add(i) last_banned_beatmaps.add(i)
await session.execute(delete(PPBestScore).where(col(PPBestScore.beatmap_id) == i)) await session.execute(delete(BestScore).where(col(BestScore.beatmap_id) == i))
scores = (await session.exec(select(Score).where(Score.beatmap_id == i, Score.pp > 0))).all() scores = (await session.exec(select(Score).where(Score.beatmap_id == i, Score.pp > 0))).all()
for score in scores: for score in scores:
score.pp = 0 score.pp = 0
@@ -58,7 +58,7 @@ async def recalculate_banned_beatmap():
logger.exception(f"Failed to query scores for unbanned beatmap {beatmap_id}") logger.exception(f"Failed to query scores for unbanned beatmap {beatmap_id}")
continue continue
prev: dict[tuple[int, int], PPBestScore] = {} prev: dict[tuple[int, int], BestScore] = {}
for score in scores: for score in scores:
attempts = 3 attempts = 3
while attempts > 0: while attempts > 0:
@@ -90,7 +90,7 @@ async def recalculate_banned_beatmap():
continue continue
key = (score.beatmap_id, score.user_id) key = (score.beatmap_id, score.user_id)
if key not in prev or prev[key].pp < pp: if key not in prev or prev[key].pp < pp:
best_score = PPBestScore( best_score = BestScore(
user_id=score.user_id, user_id=score.user_id,
beatmap_id=beatmap_id, beatmap_id=beatmap_id,
acc=score.accuracy, acc=score.accuracy,

View File

@@ -12,9 +12,9 @@ from app.calculator import (
) )
from app.config import settings from app.config import settings
from app.const import BANCHOBOT_ID from app.const import BANCHOBOT_ID
from app.database import BestScore, UserStatistics from app.database import TotalScoreBestScore, UserStatistics
from app.database.beatmap import Beatmap from app.database.beatmap import Beatmap
from app.database.best_scores import PPBestScore from app.database.best_scores import BestScore
from app.database.score import Score, calculate_playtime, calculate_user_pp from app.database.score import Score, calculate_playtime, calculate_user_pp
from app.dependencies.database import engine, get_redis from app.dependencies.database import engine, get_redis
from app.dependencies.fetcher import get_fetcher from app.dependencies.fetcher import get_fetcher
@@ -42,8 +42,8 @@ async def recalculate():
fetcher = await get_fetcher() fetcher = await get_fetcher()
redis = get_redis() redis = get_redis()
for mode in GameMode: for mode in GameMode:
await session.execute(delete(PPBestScore).where(col(PPBestScore.gamemode) == mode))
await session.execute(delete(BestScore).where(col(BestScore.gamemode) == mode)) await session.execute(delete(BestScore).where(col(BestScore.gamemode) == mode))
await session.execute(delete(TotalScoreBestScore).where(col(TotalScoreBestScore.gamemode) == mode))
await session.commit() await session.commit()
logger.info(f"Recalculating for mode: {mode}") logger.info(f"Recalculating for mode: {mode}")
statistics_list = ( statistics_list = (
@@ -63,7 +63,7 @@ async def recalculate():
) )
await run_in_batches( await run_in_batches(
[ [
_recalculate_best_score(statistics.user_id, statistics.mode, session) _recalculate_total_score_best_score(statistics.user_id, statistics.mode, session)
for statistics in statistics_list for statistics in statistics_list
], ],
batch_size=200, batch_size=200,
@@ -97,7 +97,7 @@ async def _recalculate_pp(
) )
) )
).all() ).all()
prev: dict[int, PPBestScore] = {} prev: dict[int, BestScore] = {}
async def cal(score: Score): async def cal(score: Score):
time = 10 time = 10
@@ -120,7 +120,7 @@ async def _recalculate_pp(
return return
score.pp = pp score.pp = pp
if score.beatmap_id not in prev or prev[score.beatmap_id].pp < pp: if score.beatmap_id not in prev or prev[score.beatmap_id].pp < pp:
best_score = PPBestScore( best_score = BestScore(
user_id=user_id, user_id=user_id,
beatmap_id=beatmap_id, beatmap_id=beatmap_id,
acc=score.accuracy, acc=score.accuracy,
@@ -153,13 +153,13 @@ async def _recalculate_pp(
session.add(best_score) session.add(best_score)
async def _recalculate_best_score( async def _recalculate_total_score_best_score(
user_id: int, user_id: int,
gamemode: GameMode, gamemode: GameMode,
session: AsyncSession, session: AsyncSession,
): ):
async with SEMAPHORE: async with SEMAPHORE:
beatmap_best_score: dict[int, list[BestScore]] = {} beatmap_best_score: dict[int, list[TotalScoreBestScore]] = {}
scores = ( scores = (
await session.exec( await session.exec(
select(Score).where( select(Score).where(
@@ -176,7 +176,7 @@ async def _recalculate_best_score(
): ):
continue continue
mod_for_save = mod_to_save(score.mods) mod_for_save = mod_to_save(score.mods)
bs = BestScore( bs = TotalScoreBestScore(
user_id=score.user_id, user_id=score.user_id,
score_id=score.id, score_id=score.id,
beatmap_id=score.beatmap_id, beatmap_id=score.beatmap_id,