使用Python jsonschema验证日期时间值

7
我正在使用jsonschema验证我的python字典。我尝试验证datetime值,但是我不确定如何做。
到目前为止,这是我所拥有的,但由于jsonschema没有datetime类型,因此会导致错误:
order = {
    "name": "shirt",
    "order_datetime": datetime.datetime(2018, 1, 18)
}

schema = {
    "title": "Order",
    "type": "object",
    "required": ["name", "order_datetime"],
    "properties": {
        "name": {
            "type": "string"
        },
        "order_datetime": {
            "type": "datetime"
        }
    }
}

from jsonschema import validate
validate(order, schema)

错误是jsonschema.exceptions.SchemaError: 'datetime'在任何给定的模式下都无效 。我该如何正确验证它?

文档建议使用破折号 'date-time' 拼写。并且查看其中一个模式,它被描述为“有效的日期时间字符串”,而不是 datetime 实例。 - Steven Rumbalski
@StevenRumbalski 我需要验证一个日期时间实例。 - Johnny Metz
请点击我在@sobek的回答中留下的第一个链接,了解如何扩展类型。你需要扩展的不是“数字”而是“日期时间”。 - Steven Rumbalski
1
如果您实际上不打算转储为JSON,只是想验证您的字典,请使用schema - Steven Rumbalski
4个回答

13

这是如何使用本机Python datetime对象进行正确验证的方法。 假设您有jsonschema 3.x:

from datetime import datetime
import jsonschema

def validate_with_datetime(schema, instance):
  BaseVal = jsonschema.Draft7Validator

  # Build a new type checker
  def is_datetime(checker, inst):
    return isinstance(inst, datetime)
  date_check = BaseVal.TYPE_CHECKER.redefine('datetime', is_datetime)

  # Build a validator with the new type checker
  Validator = jsonschema.validators.extend(BaseVal, type_checker=date_check)

  # Run the new Validator
  Validator(schema=schema).validate(instance)

3

一旦您将rfc3339-validatorstrict-rfc3339添加到项目依赖项中(从我看来,第一个更准确),jsonschema.FormatChecker类将注册date-time格式验证器。因此,代码应该尽可能简单:

from jsonschema import (
    Draft7Validator,
    FormatChecker,
)

schema = {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "datetime": {
      "type": "string",
      "format": "date-time"
    }
  }
}

validator = Draft7Validator(schema, format_checker=FormatChecker())
data_samples = [
    {'datetime': '2021-01-01T00:01:02.003+01:00'},
    {'datetime': '2021-01-01'},
]
assert validator.is_valid(data_samples[0]) is True
assert validator.is_valid(data_samples[1]) is False

你可以查看jsonschema文档页,了解其他可能使用的格式、所需的库以及其他提示。

1
通过@speedplane的回答帮助,我能够让类型检查器在我的order_datetime案例中正常工作。

order = {
    "name": "shirt",
    "order_datetime": "2019-09-13-22.30.00.000000"
}

schema = {
    "title": "Order",
    "type": "object",
    "required": ["name", "order_datetime"],
    "properties": {
        "name": {
            "type": "string"
        },
        "order_datetime": {
            "type": "orderdatetime"
        }
    }
}

Python 代码

import jsonschema
def validate_with_datetime(schema, instance):
  BaseVal = jsonschema.Draft7Validator
  # Build a new type checker
  def is_datetime(checker, inst):
     try:
        datetime.datetime.strptime(inst, '%Y-%m-%d-%H.%M.%S.%f')
        return True
     except ValueError:
        return False
  date_check = BaseVal.TYPE_CHECKER.redefine(u'orderdatetime', is_datetime)
  

  # Build a validator with the new type checker
  Validator = jsonschema.validators.extend(BaseVal, type_checker=date_check)

  # Run the new Validator
  Validator(schema=schema).validate(instance)

validate_with_datetime(schema, order)

但是在探索jsonschema库时,我遇到了FormatChecker()。

我们不能使用jsonschema.FormatChecker()来验证datetime类型属性的格式吗?

@speedplane你能否发布一个如何使用FormatChecker()的示例?


0
只需将您的日期时间值作为字符串传递即可。
schema={"type":'object',
        "required":['date'],
        "properties":{"date":{'type':'string',format:'date-time'}}})

validate({'date':str(datetime.datetime(2023, 7, 27, 10, 33, 26, 569990))},schema)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接