Compare commits

...

3 Commits
1.0.3 ... 1.0.4

Author SHA1 Message Date
03d34c5572 🔖 1.0.4 2024-05-07 17:22:46 +08:00
04b480ef52 🗃️ HistoricalData 添加 user_unique_identifier 字段 2024-05-07 17:21:52 +08:00
5563b01937 Revert " 为使用了 alias 的 pydantic model 设置 populate_by_name"
This reverts commit 17690e673f.
2024-05-07 08:51:55 +08:00
8 changed files with 110 additions and 64 deletions

View File

@@ -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 ###

View File

@@ -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

View File

@@ -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

View File

@@ -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):

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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'