将数据从 csv 文件加载到 Django 模型中

jay*_*eue 1 csv django django-models python-2.7

我有一个简单但令人沮丧的问题,我似乎无法弄清楚。

我正在尝试将数据从 csv 文件加载到 Django 模型中。为此,我编写了以下脚本作为视图:

import csv
def import_db(request):
    dataReader = csv.reader(open('/home/<name>/webapps/<name2>/employees.csv'), delimiter=',', quotechar='"')
    for row in dataReader:
        emp = Employee()
        emp.first_name = row[0]
        emp.last_name = row[1]
        emp.email = row[2]
        emp.level = row[3]
        emp.service_area = row[4]
        emp.service_line = row[5]
        emp.office = row[6]
        emp.save()
return HttpResponse("Completed", content_type="text/plain")
Run Code Online (Sandbox Code Playgroud)

我已将视图链接到一个网址,如下所示:

from reviews import views as emp  
url(r'^load/$',   emp.import_db, name='importdb')
Run Code Online (Sandbox Code Playgroud)

这个想法是,当我转到链接 sitename.com/load 时,我的数据将从我的 employee.csv 文件加载到我的 Employee 模型中。

问题是当我运行这个脚本时,我的 Django 模型中的 csv 文件中的每一行都有 2 个条目。我在 csv 中有 1530 个员工行,当我这样做时,模型会填充 3060 个实例。更令人讨厌的是,模型中条目的顺序与 csv 文件不同,因此我不能简单地删除 1530 个模型实例的第二个“组”。即使我在 csv 文件中使用 20 行数据的子集进行尝试,我也会得到 40 个模型实例。知道为什么会发生这种情况以及我可以做些什么来解决它吗?

非常感谢!

sol*_*oke 5

在视图函数中执行此逻辑不是一个好主意。我不知道在你的情况下到底是为什么,但有可能触发两次相同的视图功能(例如,谷歌浏览器等浏览器通常会在将 URL 粘贴到地址栏中后立即在后台预取它们 - 这可能导致两个击中了那个观点。我不知道这是否是这里的问题,但可能值得排除)。

您应该考虑将此逻辑移动到您可以确定性调用的自定义管理命令中。就像是:

# myapp/management/commands/import_csv.py
from django.core.management.base import BaseCommand, CommandError


class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument('csv_file', nargs='+', type=str)

    def handle(self, *args, **options):
        for csv_file in options['csv_file']:
            dataReader = csv.reader(open(csv_file), delimiter=',', quotechar='"')
            for row in dataReader:
                emp = Employee()
                # etc...
                self.stdout.write(
                    'Created employee {} {}'.format(emp.first_name, emp.last_name)
                )
Run Code Online (Sandbox Code Playgroud)

然后你会用以下方法调用它:

./manage.py import_csv --csvfile "/home/<name>/webapps/<name2>/employees.csv"
Run Code Online (Sandbox Code Playgroud)

这种方法使您可以更好地控制正在发生的事情,并且可以更轻松地调试问题(如果仍然存在)。