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

FastAPI+SQLModel中name字段非空验证失效问题求助

问题原因及解决办法

核心问题:验证器装饰器版本不兼容

你使用的@validator是Pydantic v1的语法,而当前SQLModel默认依赖Pydantic v2,该装饰器在v2中已被弃用,需改用@field_validator才能生效。

修复步骤

  1. 导入正确的验证器装饰器
    从pydantic模块导入field_validator:

    from pydantic import field_validator
    
  2. 替换验证器装饰器并优化逻辑
    将原@validator('name')替换为@field_validator('name'),并添加mode='before'参数确保在数据类型转换前执行验证,拦截全空格的空字符串:

    @field_validator('name', mode='before')
    def name_must_not_be_empty(cls, v):
        if not v or v.strip() == '':
            raise ValueError('Name cannot be empty or just whitespace')
        return v.strip()  # 可选:自动去除首尾空格,存储干净数据
    
  3. 补充字段约束逻辑
    原Field(..., min_length=1)仅限制字符串长度≥1,无法识别全空格的空字符串,结合验证器可实现更全面的校验。另外注意:nullable=False是控制数据库字段是否可为空,与Pydantic的输入数据验证作用不同。

完整修正后的代码片段

from datetime import datetime
from typing import Optional
from sqlmodel import SQLModel, Field, Session, create_engine, Depends
from fastapi import FastAPI, HTTPException
from pydantic import field_validator

app = FastAPI()

# 数据库连接示例
engine = create_engine("sqlite:///./test.db")
SQLModel.metadata.create_all(engine)

def get_session():
    with Session(engine) as session:
        yield session

# 用户表模型
class UserBase(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(..., min_length=1, nullable=False)
    email: str = Field(min_length=1, default=None, unique=True)
    password: str = Field(min_length=1)
    date_created: datetime = Field(default=datetime.now(), nullable=False)

    @field_validator('name', mode='before')
    def name_must_not_be_empty(cls, v):
        if not v or v.strip() == '':
            raise ValueError('Name cannot be empty or just whitespace')
        return v.strip()

# 创建用户响应模型
class CreateUser(SQLModel):
    message: str = 'Successfully created user'
    id: int
    name: str
    email: str

# 创建用户接口
@app.post('/users/', response_model=CreateUser)
def create_user(user: UserBase, session: Session = Depends(get_session)):
    # 检查邮箱是否已存在
    existing_user = session.query(UserBase).filter(UserBase.email == user.email).first()
    if existing_user:
        raise HTTPException(status_code=400, detail="Email already registered")
    session.add(user)
    session.commit()
    session.refresh(user)  # 刷新获取数据库生成的ID
    return {"message": "Successfully created user", "id": user.id, "name": user.name, "email": user.email}

额外说明

  • mode='before'确保验证器在Pydantic类型转换前执行,避免空字符串因类型转换绕过验证。
  • session.refresh(user)用于获取数据库自动生成的id值,避免返回None。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:04:58