python - 在导入之前检查 .csv 文件的格式是否正确,以避免将错误的数据嵌入数据库
问题描述
我正在开发一个 django 项目,该项目需要使用以 excelsheet 格式提供的批量数据更新数据库。所以基本上,如果 .csv 文件的格式正确(我的意思是正确的格式,我期望的数据格式良好的文件),用户可以上传 .csv 文件。我知道如何使用 django-import-export 导入文件,但问题是,我不知道如何执行检查,例如在更新数据库之前检查 .csv 文件是否具有正确的列名和信息。我是django的新手,请帮忙。
解决方案
检查格式正确的文件
如果您正在以编程方式导入文件,那么如果您可以加载 Dataset 对象,而不会引发任何错误,那么它就是一个格式正确的 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
检查正确的标题
在导入过程之前,您可以使用一个挂钩来检查有效的标头。因此,您可以执行以下操作来检查缺少的列:
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")
数据验证
您可以使用内置小部件在字段级别提供额外的验证。您可以随心所欲地扩展它们,以启用额外的特定于域的验证。例如,如果您只想允许 '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
确实对您描述的用例有很大帮助,但是当您不熟悉它时可能会感到困惑。深入阅读文档,我建议下载并运行示例应用程序(如果您还没有的话)。
核心导入逻辑相当简单,但如果您可以在开发过程中设置断点并逐步执行,它将节省大量时间。这将真正帮助您了解正在发生的事情。
推荐阅读
- javascript - 如何制作不同的菜单项下拉菜单
- java - Java 9:运行旧版 jar
- variables - 你可以在 Visual Studio Code 中保存变量吗?
- asynchronous - Python 3.6+ 中的异步 POST 在 while 循环中
- bash - Bash - 删除目录中只有一列的制表符分隔文件
- android - 使用 firebase ui 获取联系人有来自 firebase 的消息的联系人
- rust - 你能测试一个依赖的特性是否使用 `cfg!` 宏来设置吗?
- node.js - req.body(请求正文)在nodejs中使用ajax提交表单给出一个空值
- c++ - 没有任何额外数据成员的派生类的大小
- sql - 基于过滤条件的 T-SQL 查询列