Можно ли установить условную проверку в cerberus, Python?

Я использую пакет Python cerberus для проверки своей полезной нагрузки. Вот моя проблема:

Мне нужно сделать поле обязательным только в том случае, если какое-то поле из другой схемы имеет точное значение. Что-то типа:

    "key2": {
      "type": "string",
      "required": \\\ true if dict1.key1 == 'valueX' else false \\\
    }

Итак, моя схема должна выглядеть так:

"dict1": {
  "type": "dict",
  "schema": {
    "key1": {
      "type": "string",
      "required": true
    }
  }
},
"dict2": {
  "type": "dict",
  "schema": {
    "key2": {
      "type": "string",
      "required": \\\ true if dict1.key1 == 'valueX' else false \\\
    }
  }
}

Кто-нибудь знает способ, как этого добиться? Спасибо


person Ab B Bg Kostroš    schedule 22.05.2020    source источник


Ответы (3)


Я прочитал документацию, но не нашел ответа. В вашем примере я не уверен, что это действительно работает. Более того, я думаю, что зависимости работают иначе, чем в моем примере. Но, может быть, я ошибаюсь.

Похоже, зависимости в подсхемах не работают. Ваш пример возвращает сообщение об ошибке:

from cerberus import Validator
schema = {"dict1": {
        "type": "dict",
        "schema": {
            "key1": {
                "type": "string",
                "required": True,
                "allowed": ["valueX"]
            }
        }
    },
    "dict2": {
        "type": "dict",
        "schema": {
            "key2": {  # required if dependency matches
                "type": "string",
                "dependencies": {
                    "dict1.key1": ["valueX"]
                }
            }
        }
    }
}
payload = {
    "dict1": {
                "key1": 'valueX'
            },
     "dict2": {
                "key2": 'some_value'
            }       
    }

validator = Validator(schema)
if validator(payload):
    print('Super!')
else:
    print(str(validator.errors))

с ошибкой:

{'dict2': [{'key2': ["depends on these values: {'dict1.key1': ['valueX']}"]}]}

Но это сработало, когда я попытался установить зависимость для «dict2».

schema = {"dict1": {
        "type": "dict",
        "schema": {
            "key1": {
                "type": "string",
                "required": True#,
                #"allowed": ["valueX"]
            }
        }
    },
    "dict2": {
        "type": "dict",
        "dependencies": {
                    "dict1.key1": "sms"
                },
        "schema": {
            "key2": {  # required if dependency matches
                "type": "string"
            }
        }
    }
}

Если я ошибаюсь, пожалуйста, дайте мне знать. Решение действительно помогло бы мне. Спасибо

person Ab B Bg Kostroš    schedule 26.05.2020

Я тоже борюсь с этим, вот более короткий пример, который, как я надеялся, будет работать с использованием зависимостей. Я публикую это как ответ (но вики сообщества), так как блок кода имеет тенденцию плохо выглядеть в комментариях. Надеюсь, что все в порядке, а не создавать отдельный вопрос.

Сокращенный воспроизводимый пример

schema = {
    'field1': {
        'required': True
    }, 
    'field2': {
        'required': True,      
         'dependencies': {
             'field1': 'one'
         }
    }
}

>>> document = {'field1': 'two'}
>>> v.validate(document, schema)
False
>>> print(v.errors)

{'field2': ['required field']}

Выполнение вышеизложенного, насколько я понимаю, сделает поле 2 обязательным, если поле 1 равно «единице».

Моя вторая попытка состояла в том, чтобы не делать это обязательным:

schema = {
    'field1': {
        'required': True
    }, 
    'field2': {
        'required': False,      
         'dependencies': {
             'field1': 'one'
         }
    }
}

Однако это проходит тесты:

>>> document = {'field1': 'one'}
>>> v.validate(document, schema)
True
>>> print(v.errors)

{}

И терпит неудачу только в том случае, если я пытаюсь указать значение в «поле2», когда «поле1» не имеет утвержденного значения:

>>> document = {'field1': 'two', 'field2': 'test'}
>>> v.validate(document, schema)
False
>>> print(v.errors)

{'field2': ["depends on these values: {'field1': 'one'}"]}

Поэтому я не думаю, что этот вариант использования поддерживается Cerberus, а если и поддерживает, то я еще не нашел подходящей комбинации.

person Community    schedule 09.06.2020

person    schedule
comment
спасибо за комментарий, но он не работает (проверьте мой ответ от 26 мая. Если я делаю что-то не так, пожалуйста, дайте мне знать. Спасибо - person Ab B Bg Kostroš; 02.06.2020
comment
вы на правильном пути с правилом зависимостей, но вы смешиваете отношения, как будто это обязательное правило. также внимательно посмотрите, как обращаться к полям уровня lop с точечной нотацией. и чтение документов, безусловно, лучший совет. :-) Кстати, ваша разметка грязная. - person funky-future; 15.06.2020