mirror of
https://github.com/A-Minos/nonebot-plugin-tetris-stats.git
synced 2026-03-05 05:36:54 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 03d34c5572 | |||
| 04b480ef52 | |||
| 5563b01937 |
@@ -0,0 +1,103 @@
|
||||
"""Add user_unique_identifier field to HistoricalData
|
||||
|
||||
迁移 ID: b7fbdafc339a
|
||||
父迁移: 8a91210ce14d
|
||||
创建时间: 2024-05-07 16:55:29.527215
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from nonebot.log import logger
|
||||
|
||||
revision: str = 'b7fbdafc339a'
|
||||
down_revision: str | Sequence[str] | None = '8a91210ce14d'
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade(name: str = '') -> None:
|
||||
if name:
|
||||
return
|
||||
from nonebot_plugin_tetris_stats.version import __version__
|
||||
|
||||
if __version__ != '1.0.4':
|
||||
logger.critical('本迁移需要1.0.4版本, 请先锁定版本至1.0.4版本再执行本迁移')
|
||||
raise RuntimeError('本迁移需要1.0.4版本, 请先锁定版本至1.0.4版本再执行本迁移')
|
||||
from nonebot.compat import type_validate_json
|
||||
from pydantic import ValidationError
|
||||
from rich.progress import (
|
||||
BarColumn,
|
||||
MofNCompleteColumn,
|
||||
Progress,
|
||||
TaskProgressColumn,
|
||||
TextColumn,
|
||||
TimeRemainingColumn,
|
||||
)
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.automap import automap_base
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from nonebot_plugin_tetris_stats.game_data_processor.schemas import BaseUser
|
||||
|
||||
with op.batch_alter_table('nonebot_plugin_tetris_stats_historicaldata', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('user_unique_identifier', sa.String(length=32), nullable=True))
|
||||
batch_op.create_index(
|
||||
batch_op.f('ix_nonebot_plugin_tetris_stats_historicaldata_user_unique_identifier'),
|
||||
['user_unique_identifier'],
|
||||
unique=False,
|
||||
)
|
||||
Base = automap_base() # noqa: N806
|
||||
connection = op.get_bind()
|
||||
Base.prepare(autoload_with=connection)
|
||||
HistoricalData = Base.classes.nonebot_plugin_tetris_stats_historicaldata # noqa: N806
|
||||
|
||||
models: list[type[BaseUser]] = BaseUser.__subclasses__()
|
||||
|
||||
def json_to_model(value: str) -> BaseUser:
|
||||
for i in models:
|
||||
try:
|
||||
return type_validate_json(i, value)
|
||||
except ValidationError: # noqa: PERF203
|
||||
...
|
||||
raise ValueError
|
||||
|
||||
with Session(op.get_bind()) as session:
|
||||
count = session.query(HistoricalData).count()
|
||||
with Progress(
|
||||
TextColumn('[progress.description]{task.description}'),
|
||||
BarColumn(),
|
||||
MofNCompleteColumn(),
|
||||
TaskProgressColumn(),
|
||||
TimeRemainingColumn(),
|
||||
) as progress:
|
||||
task_id = progress.add_task('[cyan]Updateing:', total=count)
|
||||
for i in range(0, count, 100):
|
||||
for j in session.scalars(
|
||||
select(HistoricalData).where(HistoricalData.id > i).order_by(HistoricalData.id).limit(100)
|
||||
):
|
||||
model = json_to_model(j.game_user)
|
||||
try:
|
||||
j.user_unique_identifier = model.unique_identifier
|
||||
except ValueError:
|
||||
session.delete(j)
|
||||
progress.update(task_id, advance=1)
|
||||
session.commit()
|
||||
with op.batch_alter_table('nonebot_plugin_tetris_stats_historicaldata', schema=None) as batch_op:
|
||||
batch_op.alter_column('user_unique_identifier', existing_type=sa.VARCHAR(length=32), nullable=False)
|
||||
logger.success('database upgrade success')
|
||||
|
||||
|
||||
def downgrade(name: str = '') -> None:
|
||||
if name:
|
||||
return
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('nonebot_plugin_tetris_stats_historicaldata', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_nonebot_plugin_tetris_stats_historicaldata_user_unique_identifier'))
|
||||
batch_op.drop_column('user_unique_identifier')
|
||||
|
||||
# ### end Alembic commands ###
|
||||
@@ -70,6 +70,7 @@ class HistoricalData(MappedAsDataclass, Model):
|
||||
game_platform: Mapped[GameType] = mapped_column(String(32), index=True, init=False)
|
||||
command_type: Mapped[CommandType] = mapped_column(String(16), index=True, init=False)
|
||||
command_args: Mapped[list[str]] = mapped_column(JSON, init=False)
|
||||
user_unique_identifier: Mapped[str] = mapped_column(String(32), index=True, init=False)
|
||||
game_user: Mapped[BaseUser] = mapped_column(PydanticType(get_model=BaseUser.__subclasses__), init=False)
|
||||
processed_data: Mapped[BaseProcessedData] = mapped_column(
|
||||
PydanticType(get_model=BaseProcessedData.__subclasses__), init=False
|
||||
|
||||
@@ -68,6 +68,7 @@ class Processor(ABC):
|
||||
historical_data.game_platform = self.game_platform
|
||||
historical_data.command_type = self.command_type
|
||||
historical_data.command_args = self.command_args
|
||||
historical_data.user_unique_identifier = self.user.unique_identifier
|
||||
historical_data.game_user = self.user
|
||||
historical_data.processed_data = self.processed_data
|
||||
historical_data.finish_time = finish_time
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from nonebot.compat import PYDANTIC_V2
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ..typing import Rank
|
||||
from .base import FailedModel
|
||||
@@ -14,12 +13,6 @@ class _User(BaseModel):
|
||||
supporter: bool
|
||||
verified: bool
|
||||
country: str | None = None
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
|
||||
class SuccessModel(BaseSuccessModel):
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
from datetime import datetime
|
||||
from typing import Literal
|
||||
|
||||
from nonebot.compat import PYDANTIC_V2
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ..typing import Rank
|
||||
from .base import FailedModel
|
||||
@@ -114,12 +113,6 @@ class SuccessModel(BaseSuccessModel):
|
||||
connections: Connections
|
||||
friend_count: int | None = None
|
||||
distinguishment: Distinguishment | None = None
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
user: User
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from datetime import datetime
|
||||
|
||||
from nonebot.compat import PYDANTIC_V2
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from .base import FailedModel
|
||||
from .base import SuccessModel as BaseSuccessModel
|
||||
@@ -67,23 +66,11 @@ class EndContext(BaseModel):
|
||||
finesse: Finesse
|
||||
final_time: float = Field(..., alias='finalTime')
|
||||
gametype: str
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
|
||||
class _User(BaseModel):
|
||||
id: str = Field(..., alias='_id')
|
||||
username: str
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
|
||||
class _Record(BaseModel):
|
||||
@@ -93,12 +80,6 @@ class _Record(BaseModel):
|
||||
user: _User
|
||||
ts: datetime
|
||||
ismulti: bool | None = None
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
|
||||
class BaseModeRecord(BaseModel):
|
||||
@@ -121,12 +102,6 @@ class SuccessModel(BaseSuccessModel):
|
||||
|
||||
sprint: Sprint = Field(..., alias='40l')
|
||||
blitz: Blitz
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
class Zen(BaseModel):
|
||||
level: int
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
from datetime import datetime
|
||||
from typing import Literal
|
||||
|
||||
from nonebot.compat import PYDANTIC_V2
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class SuccessModel(BaseModel):
|
||||
@@ -17,12 +16,6 @@ class SuccessModel(BaseModel):
|
||||
win: str
|
||||
lose: str
|
||||
score: str
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
class UserDataTotalItem(BaseModel):
|
||||
time_map: str = Field(..., alias='timeMap')
|
||||
@@ -55,12 +48,6 @@ class SuccessModel(BaseModel):
|
||||
tspin_no_map: str = Field(..., alias='tspinNoMap')
|
||||
b2b_no_map: str = Field(..., alias='b2bNoMap')
|
||||
perfect_clear_no_map: str = Field(..., alias='perfectClearNoMap')
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
teaid: str = Field(..., alias='teaId')
|
||||
name: str
|
||||
@@ -85,13 +72,6 @@ class SuccessModel(BaseModel):
|
||||
register_date: datetime = Field(..., alias='registerDate')
|
||||
last_login_date: datetime = Field(..., alias='lastLoginDate')
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
else:
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
code: int
|
||||
success: Literal[True]
|
||||
data: Data
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = 'nonebot-plugin-tetris-stats'
|
||||
version = '1.0.3'
|
||||
version = '1.0.4'
|
||||
description = '一款基于 NoneBot2 的用于查询 Tetris 相关游戏数据的插件'
|
||||
authors = ['scdhh <wallfjjd@gmail.com>']
|
||||
readme = 'README.md'
|
||||
|
||||
Reference in New Issue
Block a user