我有以下 sqlmodel 基类和表模型,但我无法在保持约束的同时使我的
Decimal
字段可选。
PS:我已经知道这个问题已经在 pydantic 中讨论过,但该解决方案似乎不适用于 sqlmodel。
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"
# ...
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
# ...
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 库),并且如果没有约束,我的测试都会失败......
有人知道如何解决这个问题吗?
试试这个
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
值。