You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写验证器检查记录是否仅含一个值为1的字段及单动作验证实现问询

解决多字段单值验证器问题

嘿,我来帮你搞定这两个验证器的问题!

1. 编写验证器检查多个字段仅有一个整数值为1

核心思路是收集目标字段的值,统计其中等于1的数量必须严格等于1。结合SQLModel(基于Pydantic)的验证机制,推荐用root_validator实现——它能在所有字段验证完成后对整个模型数据做检查,避免逐个字段验证时的数据不全问题。

示例代码:

from sqlmodel import SQLModel, Field, root_validator

class ActionRecord(SQLModel):
    field1: int = Field(default=0)
    field2: int = Field(default=0)
    field3: int = Field(default=0)
    # 其他需要检查的字段...

    @root_validator(skip_on_failure=True)
    def exactly_one_field_is_one(cls, values):
        # 定义需要检查的目标字段列表
        target_fields = ["field1", "field2", "field3"]
        # 统计值为1的字段数量
        count_ones = sum(1 for field in target_fields if values.get(field) == 1)
        
        if count_ones != 1:
            raise ValueError("Exactly one of the target fields must be set to 1")
        
        return values

2. 修正你的MouseAction验证器问题

你当前的代码有两个关键问题:

  • sum(values)逻辑错误:在字段级@validator逐个验证时,values只包含已经验证过的字段(比如验证blur时,只有user_id和blur在values里),此时求和会得到错误结果。
  • 返回值错误:字段级验证器应该返回当前字段的原始值v,而不是values字典。

正确的做法是使用root_validator,在所有字段验证完成后检查动作字段的总和:

from sqlmodel import SQLModel, Field, root_validator

class MouseAction(SQLModel):
    user_id: int = Field(foreign_key="user.id")  # 注意foreign_key参数要传字符串形式的表名+字段
    blur: int = Field(default=0)
    focus: int = Field(default=0)
    copy_: int = Field(alias='copy', default=0)
    paste: int = Field(default=0)
    left_click: int = Field(default=0)
    right_click: int = Field(default=0)
    double_click: int = Field(default=0)

    @root_validator(skip_on_failure=True)
    def check_single_action(cls, values):
        # 收集所有动作字段的值
        action_values = [
            values["blur"], values["focus"], values["copy_"],
            values["paste"], values["left_click"], values["right_click"],
            values["double_click"]
        ]
        total_actions = sum(action_values)
        
        if total_actions > 1:
            raise ValueError('Only a single action is allowed per record')
        elif total_actions < 1:
            raise ValueError('Record must have an action/event')
        
        return values

补充说明:

  • skip_on_failure=True表示如果前面的字段验证失败,就跳过这个根验证器,避免抛出无关的错误。
  • 直接从values中取出所有动作字段的值求和,确保统计的是完整的所有字段数据,能准确判断是否有且仅有一个动作被设置为1(假设你的动作字段仅取值0或1)。

内容的提问来源于stack exchange,提问作者HALLOWEEN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:27:50