2010-11-03 5 views
1

Je veux écrire un script Python pour importer le contenu du fichier CSV dans la base de données d'une application Django. Ainsi, pour chaque enregistrement CSV, je crée une instance de mon modèle, définissez les valeurs appropriées à partir de la ligne CSV analysée et appelez save sur l'instance du modèle. Par exemple, voir ci-dessous:Django: Importer un fichier CSV et gérer correctement le conflit des valeurs uniques

for row in dataReader: 
    person=Person() 
    person.name=row[0] 
    person.age=row[1] 
    person.save() 

Maintenant, disons que le nom Champ est marqué comme unique dans le modèle. Quelle est la meilleure façon de gérer la situation où l'enregistrement importé a la même valeur Nom que celle déjà dans la base de données? Dois-je vérifier pour cela avant d'appeler enregistrer? Comment? Devrais-je attraper une exception? À quoi ressemblerait le code?

EDIT: Si un enregistrement existe déjà dans la base de données avec le même champ de nom, je voudrais quand même mettre à jour les autres champs. Par exemple, si j'importais Fred, 43 et il y avait déjà un record Fred, 42 dans la DB, il devrait mettre à jour la DB à Fred, 43.

EDIT: Merci pour toutes les réponses. Cette approche, pointée par chefsmart, est celui que je pense que je vais aller avec:

try: 
    obj = Person.objects.get(name=name) 
except Person.DoesNotExist: 
    obj = Person() 
    obj.name = name 
obj.age = age 
obj.save() 
+0

Une solution naïve serait d'obtenir une liste de noms à l'avance et de vérifier: si nom dans name_list: faites le save(). Je ne sais pas si c'est le meilleur. –

Répondre

0

Catch the django.db.IntegrityError, je pense

+0

J'ai essayé cela, mais après avoir attrapé l'exception, il s'arrête avec: django.db.utils.DatabaseError: la transaction en cours est annulée, les commandes ignorées jusqu'à la fin du bloc de transaction – FunLovinCoder

+0

Que faites-vous lorsque vous attrapez IntegrityError? Jetez le modèle que vous venez de créer qui contient le doublon, oui? Si oui, peut-être que vous avez à faire un get_or_create –

+0

postgres déteste la vérification d'erreur d'intégrité .... mais mysql fonctionne bien avec elle – mossplix

5

Une des fonctions ORM Django que j'aime tant est get_or_create()

donc je vous suggère de faire comme ceci:

for row in dataReader: 
    person_record, created = person.get_or_create(name=row[0], age=row[1]) 

vous pouvez vérifier après si vous voulez changer l'ancien record en person_record ou che ck si l'enregistrement a été créé if created: et faire ce que vous voulez avec elle ..

espère que cela aidera

+0

Si l'enregistrement existe déjà, mais certains des champs non uniques sont différents fait-il une mise à jour? Dois-je appeler une méthode telle que person_record.save()? – FunLovinCoder

+0

non, il ne fait pas une mise à jour est comme le nom de la méthode dire; __get si existe ou en crée un nouveau__ si vous voulez mettre à jour l'enregistrement __get_or_create__ retourne l'enregistrement s'il existe dans ma réponse c'est le var __person_record__ donc vous pouvez le changer et enregistrer() – mouad

1

Quelque chose comme ça:

for row in dataReader: 
    try: 
     Person.objects.get(name=row[0]) 
     #write some errlog here possibly or update the model 
    except Person.DoesNotExist: 
     Person.object.create(name=row[0],age=row[1]) 

Il sera peut-être mieux de savoir que vous trébuché dans dupliquer ou non. Aussi, vous ne dépendez pas si le modèle a été correctement écrit ou base de données prend en charge des clés uniques, etc.

Questions connexes