使用Pyvaru进行批量数据(CSV)验证

时间:2017-05-04 11:04:26

标签: python validation csv python-3.5

我正在寻找一个通用的验证器模块来帮助清理数据,重要的是,提供一个错误日志,说明数据被拒绝的原因。我主要使用CSV文件,每个文件平均有40列,大约有40,000行。 CSV文件将包含个人识别信息,联系信息以及他们与我们持有的帐户的详细信息

E.g。

First Name|Last Name|Other Name|Passport Number|Date of Birth|Phone Number|Email Address|Physical Address|Account Number|Invoice Number|Date Opened|Amount Due|Date Due|etc|etc

我需要验证基本内容,例如data typedata lengthoptions/choicesrangesmandatory fields等。还有条件验证,例如如果已提供Amount Due值,则还必须提供Date Due。如果它没有,那么我就提出错误。

Pyvaru 提供了一些基本的验证类。是否有可能实现基本验证的这种情况加上pyvaru的条件验证?如果是,我将如何构建验证。我必须创建对象,例如标识符对象,然后帐户对象让我使用pyvaru?

1 个答案:

答案 0 :(得分:0)

Pyvaru验证python对象(类实例和集合,如字典,列表等),因此从CSV开始我会使用DictReader将每条记录转换为字典。 因此,给出如下的CSV:

policyID,statecode,county,eq_site_limit,hu_site_limit,fl_site_limit,fr_site_limit,tiv_2011,tiv_2012,eq_site_deductible,hu_site_deductible,fl_site_deductible,fr_site_deductible,point_latitude,point_longitude,line,construction,point_granularity
119736,FL,CLAY COUNTY,498960,498960,498960,498960,498960,792148.9,0,9979.2,0,0,30.102261,-81.711777,Residential,Masonry,1
448094,FL,CLAY COUNTY,1322376.3,1322376.3,1322376.3,1322376.3,1322376.3,1438163.57,0,0,0,0,30.063936,-81.707664,Residential,Masonry,3
206893,FL,CLAY COUNTY,190724.4,190724.4,190724.4,190724.4,190724.4,192476.78,0,0,0,0,30.089579,-81.700455,Residential,Wood,1
333743,FL,CLAY COUNTY,0,79520.76,0,0,79520.76,86854.48,0,0,0,0,30.063236,-81.707703,Residential,Wood,3
172534,FL,CLAY COUNTY,0,254281.5,0,254281.5,254281.5,246144.49,0,0,0,0,30.060614,-81.702675,Residential,Wood,1

验证码类似于:

import csv
from pyvaru import Validator
from pyvaru.rules import MaxLengthRule, MaxValueRule


class CsvRecordValidator(Validator):
    def get_rules(self) -> list:
        record: dict = self.data
        return [
            MaxLengthRule(apply_to=record.get('statecode'),
                          label='State Code',
                          max_length=2),
            MaxValueRule(apply_to=record.get('eq_site_limit'),
                         label='Site limit',
                         max_value=40000),
        ]


with open('sample.csv', 'r') as csv_file:
    reader = csv.DictReader(csv_file)
    row = 0
    for record in reader:
        row += 1
        validator = CsvRecordValidator(record)
        validation = validator.validate()
        if not validation.is_successful():
            print(f'Row {row} did not validate. Details: {validation.errors}')

上面的例子只是你可以做什么的一个愚蠢的例子,特别是它检查" statecode"列的最大长度为2,并且#eq_site_limit"最大值为40k。 您可以通过继承抽象类ValidationRule并实现apply()方法来实现自己的规则:

class ContainsHelloRule(ValidationRule):
    def apply(self) -> bool:
        return 'hello' in self.apply_to

也可以使用按位运算符来否定规则...例如,通过使用先前的自定义规则来检查字符串mst是否包含" hello"你可以写:

~ ContainsHelloRule(apply_to=a_string, label="A test string")

因此只有当字符串不包含" hello"时,规则才有效。字符串。

还可以通过使用带有验证正则表达式的PatternRule验证每一行来验证CSV记录,而不进行字典转换...但当然您不知道哪个列值无效。< / p>