web-dev-qa-db-fra.com

Validation simple des données

J'écris un module python qui contiendra des fonctions qui manipuleront une base de données mongodb.

Comment puis-je valider les données d'entrée transmises à cette fonction avant de les enregistrer dans la base de données?

Par exemple, disons que l'une des fonctions du module est createUser(user) qui accepte un dictionnaire python comme argument. Ce dictionnaire contient des informations utilisateur à enregistrer dans la base de données. Je veux créer une routine de validation automatisée qui vérifie que la structure du dictionnaire correspond à la structure de la base de données.

23
anujkk

J'ai publié "pyvaru" ( https://github.com/daveoncode/pyvar ) il y a quelques jours, c'est une bibliothèque de validation de données simple, flexible et discrète pour Python 3 (3.4+), basé sur le concept de règles de validation.

Citation du doc:

Compte tenu d'un modèle existant à valider, comme celui ci-dessous (mais il pourrait s'agir d'un simple dictionnaire ou de toute structure de données puisque pyvaru ne fait aucune hypothèse sur le format des données):

class User:
    def __init__(self, first_name: str, last_name: str, date_of_birth: datetime, sex: str):
        self.first_name = first_name
        self.last_name = last_name
        self.date_of_birth = date_of_birth
        self.sex = sex

Nous devons définir un validateur, en implémentant la méthode get_rules () et pour chaque champ que nous voulons valider nous devons fournir une ou plusieurs règle (s) appropriée (s).

from pyvaru import Validator
from pyvaru.rules import TypeRule, FullStringRule, ChoiceRule, PastDateRule

class UserValidator(Validator):
    def get_rules(self) -> list:
        user = self.data # type: User
        return [
            TypeRule(apply_to=user,
                     label='User',
                     valid_type=User,
                     error_message='User must be an instance of user model.',
                     stop_if_invalid=True),
            FullStringRule(user.first_name, 'First name'),
            FullStringRule(user.last_name, 'Last name'),
            ChoiceRule(user.sex, 'Sex', choices=('M', 'F')),
            PastDateRule(user.date_of_birth, 'Date of birth')
        ]

Enfin, nous avons deux choix concernant la façon d'utiliser notre validateur personnalisé:

En tant que processeur de contexte:

with UserValidator(user):
    # do whatever you want with your valid model

Dans ce cas, le code à l'intérieur de sera exécuté uniquement si la validation réussit, sinon une exception ValidationException (contenant une propriété validation_result avec le rapport approprié) est déclenchée.

En invoquant la méthode validate () (qui renvoie un ValidationResult)

validation = UserValidator(user).validate()
if validation.is_successful():
    # do whatever you want with your valid model
else:
    # you can take a proper action and access validation.errors
    # in order to provide a useful message to the application user,
    # write logs or whatever

En supposant que nous ayons une instance d'un utilisateur configuré comme ci-dessous:

user = User(first_name=' ',
            last_name=None,
            date_of_birth=datetime(2020, 1, 1),
            sex='unknown')

En exécutant une validation avec les règles définies précédemment, nous obtiendrons un ValidationResult avec les erreurs suivantes:

{
    'First name': ['String is empty.'],
    'Last name': ['Not a string.'],
    'Sex': ['Value not found in available choices.'],
    'Date of birth': ['Not a past date.']
}
4
daveoncode