如何在 python sqlmodel 库中定义可选 [Decimal] 字段,以生成受约束的 JSON 模式

问题描述 投票:0回答:1

我有以下 sqlmodel 基类和表模型,但我无法在保持约束的同时使我的

Decimal
字段可选。 PS:我已经知道这个问题已经在 pydantic 中讨论过,但该解决方案似乎不适用于 sqlmodel。

  1. 第一次尝试(错误:
    ValueError: Unknown constraint max_digits
class ItemBase(SQLModel):
  # ...
  price: Optional[Decimal] = Field(
    default=None, max_digits=7, decimal_places=4, ge=0, le=100
  )
  # ...

class ItemTable(ItemBase, table=True):
  __tablename__ = "item"
  # ...
  1. Pydantic 解决方案表示仅对十进制应用约束(https://github.com/pydantic/pydantic/discussions/7962#discussioncomment-7939114)在 sqlmodel 中它会产生错误:
    TypeError: issubclass() arg 1 must be a class
class ItemBase(SQLModel):
  # ...
  price: Optional[Annotated[Decimal, Field(
    default=None, max_digits=7, decimal_places=4, ge=0, le=100
  )]] = None
  # ...
  1. 我的代码工作解决方案是使用 sa_column 作为
    max_digits
    decimal_places
    约束,没关系,因为这在数据库方面确实很重要。
class ItemBase(SQLModel):
  price: Optional[Decimal] = Field(
    default=None, ge=0, le=100, sa_column=Column(DECIMAL(7,4)),
    regex=r"^\d+(\.\d+)?$"  # added for the string part to only accept numbers
  )

通过最后一次尝试,

le
ge
约束在Python中正常工作:

ItemTable(..., price=Decimal(123.45))  # => throws ValidationError
ItemTable(..., price=Decimal(34.12))  # => works fine

但现在我的问题是,用它生成的 json 模式将我的所有约束删除为仅:

anyOf: [{type: number}, {type: string}, {type: null}]

有问题,因为我随后使用 json 模式为我的测试创建假对象(使用 jsf 库),并且如果没有约束,我的测试都会失败......

有人知道如何解决这个问题吗?

python jsonschema sqlmodel
1个回答
0
投票

试试这个

  • 0
    相当于
    default = 0
  • multiple_of
    为您提供可整除的精度要求
  • le
    为您提供最大整数值
class ItemBase(SQLModel)
  price: Optional[Annotated[Decimal, Field(0, multiple_of=0.0001, le=1000000)]] | None

它应该产生一个像这样的模式

{
    "type": [
        "object",
        "null"
    ],
    "properties": {
        "price": {
            "type": "number",
            "maximum": 1000000,
            "multipleOf": 0.0001
        }
    }
}

这将验证最多 7 位数字,如果提供了十进制值,则应验证最多四 (4) 个精度点。

456123.1235

如果仍然失败,有相当多的答案表明

typing-extensions
包可能需要升级。

pip install --force-reinstall typing-extensions==4.5.0

我还没有挖得更深,但我想知道 pydantic 是否在生成 JSON 模式时遇到一些困难,因为定义的类型和约束之间的关键字冲突,因为类似

max_digits
相当于
maxLength
这是一个约束
type: string
值。

© www.soinside.com 2019 - 2024. All rights reserved.