2016-08-08 64 views
0

我有一個簡單但令人沮喪的問題,我似乎無法弄清楚。從csv文件加載數據到Django模型

我想從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") 

我聯繫的觀點來一個網址如下:

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

的想法是,當我去鏈接sitename.com/load,我的數據將從我的employee.csv文件加載到我的Employee模型中。

問題是,當我運行這個腳本時,我的csv文件中的每一行都在我的Django模型中得到了2個條目。我在csv中擁有1530個員工行,當我這樣做時,模型會獲得3060個實例。更令人討厭的是,模型中條目的順序與csv文件不同,所以我不能簡單地刪除第二個1530模型實例的「組」。即使我用csv文件中20行數據的一個子集嘗試它,我也會得到40個模型實例。任何想法爲什麼發生這種情況,我能做些什麼來解決它?

非常感謝!

回答

2

在視圖函數中執行此邏輯不是一個好主意。我不清楚你的情況,但是可以兩次觸發相同的查看功能(例如,像谷歌瀏覽器這樣的瀏覽器,一旦你將它們粘貼到地址欄中,就會在後臺預先獲取網址 - 這可能會導致兩次打在那個觀點上,我不知道這是否是問題,但可能值得排除)。

您應該考慮將此邏輯轉換爲custom management command,您可以確定地調用該邏輯。喜歡的東西:

# 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 csf_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) 
       ) 

你會然後把這個:

./manage.py import_csv --csvfile "/home/<name>/webapps/<name2>/employees.csv" 

這種方法爲您提供了是怎麼回事,並使其更容易調試問題(如果還有一個更控制)。

+0

謝謝!!這正是我需要的! –

1

當你打開你的文件,檢查的行數做這樣的事情:

reader = csv.reader(open('/home/<name>/webapps/<name2>/employees.csv'), delimiter=',', quotechar='"') 
    data = list(reader) 
    print len(data) # check this