在导入之前检查 .csv 文件的格式是否正确,以避免将错误的数据嵌入到数据库中 检查格式正确的文件检查标题是否正确数据验证

问题描述

我正在开发一个 django 项目,该项目需要使用以 Excel 表格格式提供的批量数据更新数据库。 因此,基本上,如果 .csv 文件格式正确,则用户可以上传 .csv 文件(我的意思是正确格式,包含我期望的数据的格式良好的文件)。我知道如何使用 django-import-export 导入文件,但问题是,我不知道如何执行检查,例如在更新数据库之前检查 .csv 文件是否具有正确的列名和信息。 我是 Django 新手,请帮忙。

解决方法

检查格式正确的文件

如果您以编程方式导入文件,那么如果您可以load a Dataset object,而不会引发任何错误,那么它就是一个格式良好的 csv 文件。所以像:

try:
  with open('data.csv','r') as fh:
    imported_data = Dataset().load(fh,headers=False)
except Exception as e:
  # you can add additional error handling / logging here if you like
  print("import fail")
  raise e

检查标题是否正确

在导入过程之前,您可以使用 a hook 来检查有效的标头。因此,您可以执行以下操作来检查缺失的列:

class YourResource(resources.ModelResource):
    fields = ('author','email')

    def before_import(self,dataset,using_transactions,dry_run,**kwargs):
        for field_name in self.fields:
            col_name = self.fields[field_name].column_name
            if col_name not in dataset.headers:
                raise ValueError(f"'{col_name}' field not in data file")

数据验证

您可以使用内置的 widgets 在字段级别提供额外的验证。您可以随心所欲地扩展这些以启用其他特定于域的验证。例如,如果您只想允许 '1' 或 0' 作为您的布尔值,您可以实现以下内容:

class StrictBooleanWidget(widgets.BooleanWidget):
    TRUE_VALUES = ["1"]
    FALSE_VALUES = ["0"]
    NULL_VALUES = [""]

    def clean(self,value,row=None,*args,**kwargs):
        if value in self.NULL_VALUES:
            return None
        if value in self.TRUE_VALUES:
            return True
        if value in self.FALSE_VALUES:
            return False
        raise ValueError("Invalid boolean: value must be 1 or 0.")

然后在您的资源中引用此内容:

class YourResource(resources.ModelResource):
    is_active = fields.Field(
        attribute="active",column_name="active",default=False,widget=upload.widgets.StrictBooleanWidget(),)

您也可以使用这种方法来检查数据中的缺失值或空值。

django-import-export 对于您描述的用例确实有很大帮助,但是当您不熟悉它时可能会感到困惑。深入阅读文档,我建议下载并运行 example application(如果您还没有)。

核心导入逻辑相当简单,但如果您可以在开发过程中设置断点和单步执行,它将节省大量时间。这将真正帮助您了解正在发生的事情。