Skip to content

Commit

Permalink
迁移至sqlalchemy 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ssttkkl committed Mar 16, 2023
1 parent f81108f commit ce92653
Show file tree
Hide file tree
Showing 9 changed files with 372 additions and 386 deletions.
548 changes: 267 additions & 281 deletions poetry.lock

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "nonebot-plugin-mahjong-scoreboard"
version = "0.2.3"
version = "0.3.0a1"
description = "日麻寄分器(NoneBot插件)"
authors = ["ssttkkl <[email protected]>"]
readme = "README.MD"
Expand All @@ -14,7 +14,7 @@ packages = [
python = "^3.9"
nonebot2 = "^2.0.0rc1"
nonebot-adapter-onebot = "^2.1.5"
nonebot-plugin-sqlalchemy = "^0.1.7"
nonebot-plugin-sqlalchemy = "^0.2.0"
aiosqlite = ">=0.17,<0.19"
tzlocal = "^4.2"
nonebot_plugin_apscheduler = "^0.2.0"
Expand All @@ -24,7 +24,6 @@ nonebot-plugin-gocqhttp-cross-machine-upload-file = "^0.1.3"
[tool.poetry.group.dev.dependencies]
nonebug = "^0.2.1"
flake8 = "^5.0.4"
sqlalchemy2-stubs = "^0.0.2a29"
nonebot2 = {extras = ["fastapi"], version = "^2.0.0rc3"}

[build-system]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sqlalchemy import Column, String, JSON, inspect, select
from sqlalchemy import JSON, inspect, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Mapped, mapped_column

from .src import data_source

Expand All @@ -10,11 +11,11 @@
class MetaInfoOrm:
__tablename__ = 'metainfo'

key: str = Column(String(64), primary_key=True)
value = Column(JSON)
key: Mapped[str] = mapped_column(primary_key=True)
value: Mapped[any] = mapped_column(JSON)


async def get_metainfo(key: str):
async def get_metainfo(key: str) -> any:
async with AsyncSession(data_source.engine) as session:
record = await session.get(MetaInfoOrm, key)
return record.value
Expand Down
76 changes: 38 additions & 38 deletions src/nonebot_plugin_mahjong_scoreboard/model/orm/game.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from datetime import datetime
from typing import List, TYPE_CHECKING, Optional

from sqlalchemy import Column, Integer, Enum, Boolean, ForeignKey, Text, Index, DateTime
from sqlalchemy.orm import relationship
from sqlalchemy import Enum, ForeignKey, Text, Index
from sqlalchemy.orm import relationship, Mapped, mapped_column

from nonebot_plugin_mahjong_scoreboard.model.enums import Wind
from ._data_source import data_source
Expand All @@ -19,39 +19,37 @@ class GameOrm:
__tablename__ = 'games'

# 应用使用的ID(全局唯一)
id: int = Column(Integer, nullable=False, primary_key=True, autoincrement=True)
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
# 外部使用的代号(群组内唯一)
code: int = Column(Integer, nullable=False)
code: Mapped[int]

group_id: int = Column(Integer, ForeignKey('groups.id'), nullable=False)
group: "GroupOrm" = relationship('GroupOrm', foreign_keys='GameOrm.group_id')
group_id: Mapped[int] = mapped_column(ForeignKey('groups.id'))
group: Mapped["GroupOrm"] = relationship(foreign_keys='GameOrm.group_id')

promoter_user_id: Optional[int] = Column(Integer, ForeignKey('users.id'))
promoter: Optional["UserOrm"] = relationship('UserOrm', foreign_keys='GameOrm.promoter_user_id')
promoter_user_id: Mapped[Optional[int]] = mapped_column(ForeignKey('users.id'))
promoter: Mapped[Optional["UserOrm"]] = relationship(foreign_keys='GameOrm.promoter_user_id')

season_id: Optional[int] = Column(Integer, ForeignKey('seasons.id'))
season: Optional["SeasonOrm"] = relationship('SeasonOrm', foreign_keys='GameOrm.season_id')
season_id: Mapped[Optional[int]] = mapped_column(ForeignKey('seasons.id'))
season: Mapped[Optional["SeasonOrm"]] = relationship(foreign_keys='GameOrm.season_id')

player_and_wind: PlayerAndWind = Column(Enum(PlayerAndWind), nullable=False,
default=PlayerAndWind.four_men_south)
state: GameState = Column(Enum(GameState), nullable=False, default=GameState.uncompleted)
player_and_wind: Mapped[PlayerAndWind] = mapped_column(Enum(PlayerAndWind),
default=PlayerAndWind.four_men_south)
state: Mapped[GameState] = mapped_column(default=GameState.uncompleted)

records: List["GameRecordOrm"] = relationship("GameRecordOrm",
foreign_keys='GameRecordOrm.game_id',
back_populates="game")
records: Mapped[List["GameRecordOrm"]] = relationship(foreign_keys='GameRecordOrm.game_id',
back_populates="game")

progress: Optional["GameProgressOrm"] = relationship("GameProgressOrm",
foreign_keys='GameProgressOrm.game_id',
uselist=False)
progress: Mapped[Optional["GameProgressOrm"]] = relationship(foreign_keys='GameProgressOrm.game_id',
uselist=False)

complete_time: Optional[datetime] = Column(DateTime)
complete_time: Mapped[Optional[datetime]]

comment: Optional[str] = Column(Text)
comment: Mapped[Optional[str]] = mapped_column(Text)

accessible: bool = Column(Boolean, nullable=False, default=True)
create_time: datetime = Column(DateTime, nullable=False, default=datetime.utcnow)
update_time: datetime = Column(DateTime, nullable=False, default=datetime.utcnow)
delete_time: Optional[datetime] = Column(DateTime)
accessible: Mapped[bool] = mapped_column(default=True)
create_time: Mapped[datetime] = mapped_column(default=datetime.utcnow)
update_time: Mapped[datetime] = mapped_column(default=datetime.utcnow)
delete_time: Mapped[Optional[datetime]]

__table_args__ = (
Index("games_season_id_idx", "season_id"),
Expand All @@ -63,36 +61,38 @@ class GameOrm:
class GameRecordOrm:
__tablename__ = 'game_records'

game_id: int = Column(Integer, ForeignKey('games.id'), primary_key=True, nullable=False)
game: "GameOrm" = relationship('GameOrm', foreign_keys='GameRecordOrm.game_id', back_populates='records')
game_id: Mapped[int] = mapped_column(ForeignKey('games.id'), primary_key=True)
game: Mapped["GameOrm"] = relationship(foreign_keys='GameRecordOrm.game_id',
back_populates='records')

user_id: int = Column(Integer, ForeignKey('users.id'), primary_key=True, nullable=False)
user: "UserOrm" = relationship('UserOrm', foreign_keys='GameRecordOrm.user_id')
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'), primary_key=True)
user: Mapped["UserOrm"] = relationship(foreign_keys='GameRecordOrm.user_id')

wind: Optional[Wind] = Column(Enum(Wind))
wind: Mapped[Optional[Wind]]

score: int = Column(Integer, nullable=False) # 分数
score: Mapped[int] # 分数

# 真正PT=raw_point*10^point_scale,例如point_scale=0时缩放1x,point_scale=-1时缩放0.1x
raw_point: int = Column('point', Integer, nullable=False, default=0) # pt
point_scale: int = Column(Integer, nullable=False, default=0) # pt缩放比例
raw_point: Mapped[int] = mapped_column('point', default=0) # pt
point_scale: Mapped[int] = mapped_column(default=0) # pt缩放比例

@property
def point(self) -> float:
return self.raw_point * 10 ** self.point_scale

rank: Optional[int] = Column("rnk", Integer) # 排名
rank: Mapped[Optional[int]] = mapped_column("rnk") # 排名


@data_source.registry.mapped
class GameProgressOrm:
__tablename__ = 'game_progresses'

game_id: int = Column(Integer, ForeignKey('games.id'), primary_key=True, nullable=False)
game: "GameOrm" = relationship('GameOrm', foreign_keys='GameProgressOrm.game_id', back_populates='progress')
game_id: Mapped[int] = mapped_column(ForeignKey('games.id'), primary_key=True)
game: Mapped["GameOrm"] = relationship(foreign_keys='GameProgressOrm.game_id',
back_populates='progress')

round: int = Column(Integer, nullable=False)
honba: int = Column(Integer, nullable=False)
round: Mapped[int]
honba: Mapped[int]


__all__ = ("GameOrm", "GameRecordOrm", "GameProgressOrm")
18 changes: 9 additions & 9 deletions src/nonebot_plugin_mahjong_scoreboard/model/orm/group.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Optional

from sqlalchemy import Column, Integer, BigInteger, ForeignKey, Index
from sqlalchemy.orm import relationship
from sqlalchemy import BigInteger, ForeignKey, Index
from sqlalchemy.orm import mapped_column, relationship, Mapped

from ._data_source import data_source

Expand All @@ -13,14 +13,14 @@
class GroupOrm:
__tablename__ = 'groups'

id: int = Column(Integer, primary_key=True, autoincrement=True)
binding_qq: int = Column(BigInteger)
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
binding_qq: Mapped[int] = mapped_column(BigInteger)

running_season_id: int = Column(Integer, ForeignKey('seasons.id'))
running_season: 'SeasonOrm' = relationship('SeasonOrm', foreign_keys='GroupOrm.running_season_id')
running_season_id: Mapped[Optional[int]] = mapped_column(ForeignKey('seasons.id'))
running_season: Mapped[Optional['SeasonOrm']] = relationship(foreign_keys='GroupOrm.running_season_id')

prev_game_code_base: int = Column(Integer)
prev_game_code_identifier: int = Column(Integer)
prev_game_code_base: Mapped[int]
prev_game_code_identifier: Mapped[int]

__table_args__ = (
Index("groups_binding_qq_idx", "binding_qq"),
Expand Down
79 changes: 39 additions & 40 deletions src/nonebot_plugin_mahjong_scoreboard/model/orm/season.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from datetime import datetime
from typing import TYPE_CHECKING, Optional, List

from sqlalchemy import Column, Integer, DateTime, String, Enum, ForeignKey, Boolean, Index
from sqlalchemy.orm import relationship
from sqlalchemy import ForeignKey, Index
from sqlalchemy.orm import mapped_column, relationship, Mapped

from ._data_source import data_source
from .types.userdict import UserDict as SqlUserDict
Expand All @@ -17,38 +17,38 @@


class SeasonConfig(UserDict):
south_game_enabled: bool = DictField()
south_game_origin_point: Optional[int] = DictField(default=None)
south_game_horse_point: Optional[List[int]] = DictField(default_factory=list)
east_game_enabled: bool = DictField()
east_game_origin_point: Optional[int] = DictField(default=None)
east_game_horse_point: Optional[List[int]] = DictField(default_factory=list)
point_precision: int = DictField(default=0) # PT精确到10^point_precision
south_game_enabled: Mapped[bool] = DictField()
south_game_origin_point: Mapped[Optional[int]] = DictField(default=None)
south_game_horse_point: Mapped[Optional[List[int]]] = DictField(default_factory=list)
east_game_enabled: Mapped[bool] = DictField()
east_game_origin_point: Mapped[Optional[int]] = DictField(default=None)
east_game_horse_point: Mapped[Optional[List[int]]] = DictField(default_factory=list)
point_precision: Mapped[int] = DictField(default=0) # PT精确到10^point_precision


@data_source.registry.mapped
class SeasonOrm:
__tablename__ = 'seasons'

id: int = Column(Integer, primary_key=True, autoincrement=True)
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)

group_id: int = Column(Integer, ForeignKey('groups.id'), nullable=False)
group: 'GroupOrm' = relationship('GroupOrm', foreign_keys='SeasonOrm.group_id')
group_id: Mapped[int] = mapped_column(ForeignKey('groups.id'))
group: Mapped['GroupOrm'] = relationship(foreign_keys='SeasonOrm.group_id')

state: SeasonState = Column(Enum(SeasonState), nullable=False, default=SeasonState.initial)
state: Mapped[SeasonState] = mapped_column(default=SeasonState.initial)

code: str = Column(String, nullable=False)
name: str = Column(String, nullable=False)
code: Mapped[str]
name: Mapped[str]

start_time: Optional[datetime] = Column(DateTime)
finish_time: Optional[datetime] = Column(DateTime)
start_time: Mapped[Optional[datetime]]
finish_time: Mapped[Optional[datetime]]

config: SeasonConfig = Column(SqlUserDict(SeasonConfig), nullable=False)
config: Mapped[SeasonConfig] = mapped_column(SqlUserDict(SeasonConfig))

accessible: bool = Column(Boolean, nullable=False, default=True)
create_time: datetime = Column(DateTime, nullable=False, default=datetime.utcnow)
update_time: datetime = Column(DateTime, nullable=False, default=datetime.utcnow)
delete_time: Optional[datetime] = Column(DateTime)
accessible: Mapped[bool] = mapped_column(default=True)
create_time: Mapped[datetime] = mapped_column(default=datetime.utcnow)
update_time: Mapped[datetime] = mapped_column(default=datetime.utcnow)
delete_time: Mapped[Optional[datetime]]

__table_args__ = (
Index("seasons_group_id_code_idx", "group_id", "code"),
Expand All @@ -59,38 +59,37 @@ class SeasonOrm:
class SeasonUserPointOrm:
__tablename__ = 'season_user_points'

season_id: int = Column(Integer, ForeignKey('seasons.id'), nullable=False, primary_key=True)
season: 'SeasonOrm' = relationship('SeasonOrm', foreign_keys='SeasonUserPointOrm.season_id')
season_id: Mapped[int] = mapped_column(ForeignKey('seasons.id'), primary_key=True)
season: Mapped['SeasonOrm'] = relationship(foreign_keys='SeasonUserPointOrm.season_id')

user_id: int = Column(Integer, ForeignKey('users.id'), nullable=False, primary_key=True)
user: 'UserOrm' = relationship('UserOrm', foreign_keys='SeasonUserPointOrm.user_id')
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'), primary_key=True)
user: Mapped['UserOrm'] = relationship(foreign_keys='SeasonUserPointOrm.user_id')

point: int = Column(Integer, nullable=False, default=0)
point: Mapped[int] = mapped_column(default=0)

create_time: datetime = Column(DateTime, nullable=False, default=datetime.utcnow)
update_time: datetime = Column(DateTime, nullable=False, default=datetime.utcnow)
create_time: Mapped[datetime] = mapped_column(default=datetime.utcnow)
update_time: Mapped[datetime] = mapped_column(default=datetime.utcnow)


@data_source.registry.mapped
class SeasonUserPointChangeLogOrm:
__tablename__ = 'season_user_point_change_logs'

id: int = Column(Integer, primary_key=True, autoincrement=True)
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)

season_id: int = Column(Integer, ForeignKey('seasons.id'), nullable=False)
season: 'SeasonOrm' = relationship('SeasonOrm', foreign_keys='SeasonUserPointChangeLogOrm.season_id')
season_id: Mapped[int] = mapped_column(ForeignKey('seasons.id'))
season: Mapped['SeasonOrm'] = relationship(foreign_keys='SeasonUserPointChangeLogOrm.season_id')

user_id: int = Column(Integer, ForeignKey('users.id'), nullable=False)
user: 'UserOrm' = relationship('UserOrm', foreign_keys='SeasonUserPointChangeLogOrm.user_id')
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
user: Mapped['UserOrm'] = relationship(foreign_keys='SeasonUserPointChangeLogOrm.user_id')

change_type: SeasonUserPointChangeType = Column(Enum(SeasonUserPointChangeType), nullable=False)
change_point: int = Column(Integer, nullable=False)
change_type: Mapped[SeasonUserPointChangeType]
change_point: Mapped[int]

related_game_id: Optional[int] = Column(Integer, ForeignKey('games.id'))
related_game: Optional['GameOrm'] = relationship('GameOrm',
foreign_keys='SeasonUserPointChangeLogOrm.related_game_id')
related_game_id: Mapped[Optional[int]] = mapped_column(ForeignKey('games.id'))
related_game: Mapped[Optional['GameOrm']] = relationship(foreign_keys='SeasonUserPointChangeLogOrm.related_game_id')

create_time: datetime = Column(DateTime, nullable=False, default=datetime.utcnow)
create_time: Mapped[datetime] = mapped_column(default=datetime.utcnow)

__table_args__ = (
Index("seasons_related_game_id_idx", "related_game_id"),
Expand Down
7 changes: 4 additions & 3 deletions src/nonebot_plugin_mahjong_scoreboard/model/orm/user.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from sqlalchemy import Column, BigInteger, Integer, Index
from sqlalchemy import BigInteger, Index
from sqlalchemy.orm import Mapped, mapped_column

from ._data_source import data_source

Expand All @@ -7,8 +8,8 @@
class UserOrm:
__tablename__ = 'users'

id: int = Column(Integer, primary_key=True, autoincrement=True)
binding_qq: int = Column(BigInteger)
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
binding_qq: Mapped[int] = mapped_column(BigInteger)

__table_args__ = (
Index("users_binding_qq_idx", "binding_qq"),
Expand Down
14 changes: 7 additions & 7 deletions src/nonebot_plugin_mahjong_scoreboard/service/game_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,22 @@ def _build_game_query(stmt: Select,
uncompleted_only: bool = False,
completed_only: bool = False,
reverse_order: bool = False,
time_span: Optional[Tuple[datetime, datetime]] = None):
time_span: Optional[Tuple[datetime, datetime]] = None) -> Select:
if uncompleted_only:
stmt.append_whereclause(GameOrm.state != GameState.completed)
stmt = stmt.where(GameOrm.state != GameState.completed)
elif completed_only:
stmt.append_whereclause(GameOrm.state == GameState.completed)
stmt = stmt.where(GameOrm.state == GameState.completed)

if reverse_order:
stmt = stmt.order_by(GameOrm.id.desc())
else:
stmt = stmt.order_by(GameOrm.id)

if time_span:
stmt.append_whereclause(GameOrm.create_time >= time_span[0])
stmt.append_whereclause(GameOrm.create_time < time_span[1])
stmt = stmt.where(GameOrm.create_time >= time_span[0])
stmt = stmt.where(GameOrm.create_time < time_span[1])

stmt.append_whereclause(GameOrm.accessible)
stmt = stmt.where(GameOrm.accessible)

stmt = (stmt.offset(offset).limit(limit)
.options(selectinload(GameOrm.records)))
Expand Down Expand Up @@ -156,7 +156,7 @@ async def get_games(group: Optional[GroupOrm] = None,
stmt = stmt.join(GameRecordOrm).where(GameRecordOrm.user == user)

if season is not None:
stmt.append_whereclause(GameOrm.season == season)
stmt = stmt.where(GameOrm.season == season)

stmt = _build_game_query(stmt, **kwargs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async def get_season_user_point_change_logs(season: Optional[SeasonOrm] = None,
stmt = stmt.where(SeasonUserPointChangeLogOrm.season == season)

if user is not None:
stmt.append_whereclause(SeasonUserPointChangeLogOrm.user == user)
stmt = stmt.where(SeasonUserPointChangeLogOrm.user == user)

if reverse_order:
stmt = stmt.order_by(SeasonUserPointChangeLogOrm.id.desc())
Expand Down

0 comments on commit ce92653

Please sign in to comment.