【问题标题】:strange validation behavior with `datetime` in sub object in python evepython eve中子对象中“datetime”的奇怪验证行为
【发布时间】:2017-09-06 12:39:16
【问题描述】:

在测试我的 python eve API 时,我看到了一些非常奇怪的验证行为。

  • 前夕 0.7.4
  • Mongod v3.2.10

简化摘要:我有一个域端点test,其架构包含一个对象props,它有两个子属性timewetBulb

DOMAIN = {

    # test end point
    'test': {
        'schema': {
            'props': {
                'type': 'dict',
                'schema': { 
                    'time':     {'type': 'datetime'},           # datetime fails to validate
                    'wetBulb':  {'type': ['string', 'float']} # only see issue while key is camel case and contains two type options
                }
            }
        },
        'resource_methods': ['GET', 'POST']
    }
}

DATE_FORMAT = '%Y-%m-%d %H:%M:%S'   # date format seems to be irrelevant

当我将wetBulb 定义为驼峰式键(即wetBulb 而不是wet_bulb)和/或将其定义为两种潜在类型之一(即'type': ['string', 'float'])时,eve/cerberus 无法解释我的time 值作为 datetime

示例:

使用所有其他默认值在本地运行,我使用 requests 库测试此 API 点:

import requests 

post = {
    'properties': {
        'time': '2017-09-05 20:17:40',
        'wetBulb': '21.200000000000003' 
    }
}

r = requests.post('http://127.0.0.1:5000/test', data=json.dumps(post), headers={'content-type': 'application/json'})

# print response
print('Status {0}'.format(r.status_code))
print(r.text)

我得到了回应

Status 422
{"_status": "ERR", "_issues": {"properties": {"time": "must be of datetime type"}}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}

如果我将架构定义更改为具有键 wet_bulb 和/或我将其类型更改为 'type': 'string',它将正确验证:

DOMAIN = {

    # test end point
    'test': {
        'schema': {
            'props': {
                'type': 'dict',
                'schema': { 
                    'time':     {'type': 'datetime'},       
                    'wet_bulb': {'type': 'string'}
                }
            }
        },
        'resource_methods': ['GET', 'POST']
    }
}

然后发布带有更新对象的对象:

post = {
    'properties': {
        'time': '2017-09-05 20:17:40',
        'wet_bulb': '21.200000000000003' 
    }
}

r = requests.post('http://127.0.0.1:5000/test', data=json.dumps(post), headers={'content-type': 'application/json'})

# print response
print('Status {0}'.format(r.status_code))
print(r.text)

Status 201
{"_updated": "2017-09-06 12:30:18", "_links": {"self": {"href": "vos/59afea5aa8a548256898cc40", "title": "Vo"}}, "_created": "2017-09-06 12:30:18", "_status": "OK", "_id": "59afea5aa8a548256898cc40", "_etag": "f1b918a2fe688941f84f4d00bc1b400abddab446"}

问题:

有没有人看到过类似的其他行为,或者可以帮助澄清什么可能控制了这种验证行为?我已经四处探索,试图定义导致验证但没有成功的原因。


编辑

我相信部分解释在 cerberus 文档中 type 下面的两个注释中,但我仍然没有弄清楚原因:

http://docs.python-cerberus.org/en/stable/validation-rules.html#type

我在不同的架构中遇到了相同的datetime 验证问题。在这种情况下,我通过删除'type' 声明或将'type' 设置为字符串而不是列表(即'type': 'number' 而不是'type': ['number', 'list'] 来解决它。不幸的是,此模式不适用于应用程序,所以我暂时删除了'type' 声明。

【问题讨论】:

  • 你能提供一个最小的非工作示例吗?如果您怀疑只是 Cerberus 是原因,请忽略 http 层。
  • 这里的描述太复杂了,很难理解问题的主要部分是什么,请简述。那么问题是什么?还要指出日期:试试这种格式~“Fri, 03 Oct 2014 08:16:52 GMT”。最好的!
  • 您的示例中的 time 字段值是字符串,而不是日期时间。要么根据正则表达式验证字符串,要么首先将其规范化为实际的 datetime 对象。

标签: python eve cerberus


【解决方案1】:

您没有在 JSON 中发送实际的 Python 日期时间。 Cerberus 日期类型是检查属性值是否为 Python 日期时间对象。 因此,您想验证一个 json 字符串,然后将其转换为 Python 日期时间。 您有两种方法,如下所述:https://stackoverflow.com/a/61320357/1417256

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    相关资源
    最近更新 更多