Genshin-bots / gsuid_core

💖一套业务逻辑,多个平台支持!异步核心框架GsCore,为插件编写提供完善平台支持、核心数据库统一、复用游戏查询逻辑、网页控制台,支持Bot列表: NoneBot2 & HoshinoBot & ZeroBot & YunZaiBot & Koishi
https://docs.sayu-bot.com
GNU General Public License v3.0
111 stars 16 forks source link

【疑问】请问单开sr推送表应该继承哪个模型 #73

Closed mengluo04 closed 2 months ago

mengluo04 commented 2 months ago

继承Push表会报错, 这是错误信息

Traceback (most recent call last):
  File "/root/.cache/pypoetry/virtualenvs/gsuid-core-K4LPybnJ-py3.10/lib/python3.10/site-packages/apscheduler/executors/base_py3.py", line 30, in run_coroutine_job
    retval = await job.func(*job.args, **job.kwargs)
  File "/home/services/gsuid_core/gsuid_core/plugins/StarRailUID/StarRailUID/starrailuid_stamina/__init__.py", line 46, in sr_notice_job
    result = await get_notice_list()
  File "/home/services/gsuid_core/gsuid_core/plugins/StarRailUID/StarRailUID/starrailuid_stamina/notice.py", line 30, in get_notice_list
    push_data = await SrPush.select_data_by_uid(user.sr_uid, 'sr')
  File "/home/services/gsuid_core/gsuid_core/utils/database/base_models.py", line 45, in wrapper
    data = await func(self, session, *args, **kwargs)
  File "/home/services/gsuid_core/gsuid_core/utils/database/base_models.py", line 1477, in select_data_by_uid
    getattr(cls, cls.get_gameid_name(game_name)) == uid,
  File "/root/.cache/pypoetry/virtualenvs/gsuid-core-K4LPybnJ-py3.10/lib/python3.10/site-packages/pydantic/_internal/_model_construction.py", line 237, in __getattr__
    raise AttributeError(item)
AttributeError: sr_uid

这是class

from typing import Optional
from sqlmodel import Field

from gsuid_core.utils.database.base_models import Push
from gsuid_core.webconsole import site
from gsuid_core.webconsole.mount_app import GsAdminModel
from fastapi_amis_admin.amis.components import PageSchema

class SrPush(Push, table=True):
    bot_id: str = Field(title='平台')
    uid: str = Field(default=None, title='星铁UID')

    stamina_push: Optional[str] = Field(
        title='体力推送',
        default='off',
        schema_extra={'json_schema_extra': {'hint': 'sr开启体力'}},
    )
    stamina_value: Optional[int] = Field(title='体力阈值', default=180)
    stamina_is_push: Optional[str] = Field(title='体力是否已推送', default='off')
    go_push: Optional[str] = Field(
        title='派遣推送',
        default='off',
        schema_extra={'json_schema_extra': {'hint': 'sr开启派遣'}},
    )
    go_is_push: Optional[str] = Field(title='派遣是否已推送', default='off')

@site.register_admin
class srpushadmin(GsAdminModel):
    pk_name = 'id'
    page_schema = PageSchema(label='星铁推送管理', icon='fa fa-bullhorn')  # type: ignore

    # 配置管理模型
    model = SrPush

这是检查推送的关键代码

async def get_notice_list() -> Dict[str, Dict[str, Dict]]:
    msg_dict: Dict[str, Dict[str, Dict]] = {}
    for _ in gss.active_bot:
        user_list = await GsUser.get_all_push_user_list()
        for user in user_list:
            if user.sr_uid is not None:
                raw_data = await mys_api.get_daily_data(user.sr_uid)
                if isinstance(raw_data, int):
                    logger.error(f'[sr推送提醒]获取{user.sr_uid}的数据失败!')
                    continue
                push_data = await SrPush.select_data_by_uid(user.sr_uid, 'sr')
                msg_dict = await all_check(
                    user.bot_id,
                    raw_data,
                    push_data.__dict__,
                    msg_dict,
                    user.user_id,
                    user.sr_uid,
                )
    return msg_dict
KimigaiiWuyi commented 2 months ago

是这样, 基类里的大部分方法通过传入的game_name确定键uid 假设你game_name传入None(不传的默认值),那就会去找uid键,其他的则去找{game_name}_uid键 假设传入sr, 则会去找sr_uid键 在你继承的SrPush表中,uid应当改为sr_uid

- uid: str = Field(default=None, title='星铁UID')
+ sr_uid: str = Field(default=None, title='星铁UID')

否则, 在下面调用的方法中, 应不传入game_name(当然不推荐, 因为会造成和GenshinUID语义上的混淆)

- push_data = await SrPush.select_data_by_uid(user.sr_uid, 'sr')
+ push_data = await SrPush.select_data_by_uid(user.sr_uid)
mengluo04 commented 2 months ago

是这样, 基类里的大部分方法通过传入的game_name确定键uid 假设你game_name传入None(不传的默认值),那就会去找uid键,其他的则去找{game_name}_uid键 假设传入sr, 则会去找sr_uid键 在你继承的SrPush表中,uid应当改为sr_uid

- uid: str = Field(default=None, title='星铁UID')
+ sr_uid: str = Field(default=None, title='星铁UID')

否则, 在下面调用的方法中, 应不传入game_name(当然不推荐, 因为会造成和GenshinUID语义上的混淆)

- push_data = await SrPush.select_data_by_uid(user.sr_uid, 'sr')
+ push_data = await SrPush.select_data_by_uid(user.sr_uid)

好的,修改了模型class之后重启没有重新生成表,是因为没有加__table_args__ = {'extend_existing': True}的原因吗

KimigaiiWuyi commented 2 months ago

是这样, 基类里的大部分方法通过传入的game_name确定键uid 假设你game_name传入None(不传的默认值),那就会去找uid键,其他的则去找{game_name}_uid键 假设传入sr, 则会去找sr_uid键 在你继承的SrPush表中,uid应当改为sr_uid

- uid: str = Field(default=None, title='星铁UID')
+ sr_uid: str = Field(default=None, title='星铁UID')

否则, 在下面调用的方法中, 应不传入game_name(当然不推荐, 因为会造成和GenshinUID语义上的混淆)

- push_data = await SrPush.select_data_by_uid(user.sr_uid, 'sr')
+ push_data = await SrPush.select_data_by_uid(user.sr_uid)

好的,修改了模型class之后重启没有重新生成表,是因为没有加__table_args__ = {'extend_existing': True}的原因吗

修改模型class之后确实不会重新生成表, 你需要删表再生成, __table_args__ = {'extend_existing': True}是为了在继承的时候, 额外添加列, 不是在修改模型的时候添加类

mengluo04 commented 2 months ago

是这样, 基类里的大部分方法通过传入的game_name确定键uid 假设你game_name传入None(不传的默认值),那就会去找uid键,其他的则去找{game_name}_uid键 假设传入sr, 则会去找sr_uid键 在你继承的SrPush表中,uid应当改为sr_uid

- uid: str = Field(default=None, title='星铁UID')
+ sr_uid: str = Field(default=None, title='星铁UID')

否则, 在下面调用的方法中, 应不传入game_name(当然不推荐, 因为会造成和GenshinUID语义上的混淆)

- push_data = await SrPush.select_data_by_uid(user.sr_uid, 'sr')
+ push_data = await SrPush.select_data_by_uid(user.sr_uid)

好的,修改了模型class之后重启没有重新生成表,是因为没有加__table_args__ = {'extend_existing': True}的原因吗

修改模型class之后确实不会重新生成表, 你需要删表再生成, __table_args__ = {'extend_existing': True}是为了在继承的时候, 额外添加列, 不是在修改模型的时候添加类

好的,明白了,删了重新生成字段就对了