【问题标题】:Check if JSON string is valid Pydantic schema检查 JSON 字符串是否是有效的 Pydantic 模式
【发布时间】:2021-03-26 11:21:44
【问题描述】:

我想检查一个 JSON 字符串是否是一个有效的 Pydantic 模式。

from pydantic import BaseModel

class MySchema(BaseModel):
    val: int

我可以通过 try/except 非常简单地做到这一点:

import json

valid = '{"val": 1}'
invalid = '{"val": "horse"}'

def check_valid(item):
    try:
        MySchema(**json.loads(item))
        return True
    except:
        return False

print(check_valid(valid))
print(check_valid(invalid))

输出:

True
False

使用 try/except 来获得真/假似乎是不好的做法。有没有更好的办法?

【问题讨论】:

  • 最好是捕获特定的异常。在这种情况下,来自 pydantic 的 ValidationError 和来自 json.loads 的异常
  • 顺便说一下pydantic默认有一些类型转换,所以要注意。所以 pydantic 不仅是验证器,还是格式化器

标签: python validation pydantic


【解决方案1】:

我认为这是一个很好的方法,我只建议将 JSON 解析与模型实例化分开处理,并在捕获异常时更加具体,见下文:

import pydantic
import json

class MySchema(pydantic.BaseModel):
    val: int

invalid_json = '{"invalid": 123'
invalid_value = '{"val": "horse"}'
invalid_key = '{"wrong_key": 1}'

valid = '{"val": 1}'
valid_2 = '{"val": "1"}'

def check_valid(item):
    try:
        json_item = json.loads(item)

    # Catch potential JSON formatting problems:
    except json.JSONDecodeError as exc:
        print(f"ERROR: Invalid JSON: {exc.msg}, line {exc.lineno}, column {exc.colno}")
        return False

    try:
        MySchema(**json_item)

    # Catch pydantic's validation errors:
    except pydantic.ValidationError as exc:
        print(f"ERROR: Invalid schema: {exc}")
        return False

    return True

print(check_valid(invalid_json))
# ERROR: Invalid JSON: Expecting ',' delimiter, line 1, column 16
# False

print(check_valid(invalid_value))
# ERROR: Invalid schema: 1 validation error for MySchema
# val
#   value is not a valid integer (type=type_error.integer)
# False

print(check_valid(invalid_key))
# ERROR: Invalid schema: 1 validation error for MySchema
# val
#   field required (type=value_error.missing)
# False

print(check_valid(valid))
# True

print(check_valid(valid_2))
# True

当然,您可以将逻辑拆分为两个函数,一个负责 JSON 验证,另一个负责 pydantic 模型。

【讨论】:

    【解决方案2】:
    import pydantic
    
    class MySchema(pydantic.BaseModel):
        val: int
    
    MySchema.parse_raw('{"val": 1}')
    MySchema.parse_raw('{"val": "horse"}')
    

    我认为这将是最简单的解决方案:)

    【讨论】:

      猜你喜欢
      • 2013-02-13
      • 2022-01-19
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 2018-08-21
      • 1970-01-01
      • 2019-05-05
      • 2019-10-04
      相关资源
      最近更新 更多