2016-08-08 60 views
0

Ich habe ein einfaches, aber frustrierendes Problem, das ich nicht herausfinden kann.Laden von Daten aus einer CSV-Datei in ein Django-Modell

Ich versuche, Daten aus einer CSV-Datei in ein Django-Modell zu laden. Um dies zu tun habe ich das folgende Skript als Ansicht geschrieben:

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") 

ich die Ansicht auf eine URL verknüpft haben, wie folgt:

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

Die Idee ist, dass, wenn ich auf den Link gehen sitename.com/load, meine Daten werden von meiner employee.csv-Datei in mein Mitarbeitermodell geladen.

Das Problem ist, wenn ich dieses Skript ausführen, bekomme ich 2 Einträge in meinem Django-Modell für jede Zeile in meiner CSV-Datei. Ich habe 1530 Mitarbeiter Zeilen in der CSV und das Modell wird mit 3060 Instanzen bevölkert, wenn ich dies tun. Was noch ärgerlicher ist, ist, dass die Reihenfolge der Einträge in dem Modell nicht mit der CSV-Datei übereinstimmt, so dass ich die zweite "Gruppe" von 1530 Modellinstanzen nicht einfach löschen kann. Selbst wenn ich es mit einer Teilmenge von 20 Datenzeilen in der CSV-Datei versuche, erhalte ich 40 Modellinstanzen. Irgendeine Idee, warum das passiert und was ich tun kann, um es zu beheben?

Vielen Dank!

Antwort

2

Das Ausführen dieser Logik in einer Ansichtsfunktion ist keine gute Idee. Ich weiß nicht genau, warum in Ihrem Fall, aber es ist möglich, die gleiche Ansichtsfunktion zweimal zu aktivieren (zB Browser wie Google Chrome URLs im Hintergrund oft vorab abholen, sobald Sie sie in die Adressleiste einfügen - das kann zwei verursachen Hits auf diese Sicht. Ich weiß nicht, ob das hier das Problem ist, aber es kann sich lohnen, auszuschließen.

Sie sollten diese Logik in eine custom management command verschieben, die Sie deterministisch aufrufen können. Etwas wie:

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

würden Sie dann nennen dies mit:

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

Dieser Ansatz gibt Ihnen mehr Kontrolle darüber, was los ist und wird es einfacher, das Problem zu debuggen (wenn es noch ein ist).

+0

DANKE !! Das ist genau das, was ich brauchte !!! –

1

Wo Sie Ihre Datei öffnen, überprüfen Anzahl der Zeilen etwas tun, wie folgt aus:

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