J'utilise la classe suivante dans models.py:save() supprime enregistrement existant lors de l'utilisation unique_together dans le modèle Django
class Player(models.Model):
id = models.AutoField(primary_key=True)
sport = models.CharField(max_length=3, choices=SPORT_CHOICES)
yid = models.IntegerField()
first = models.CharField(max_length=30)
last = models.CharField(max_length=30)
team = models.CharField(max_length=3)
class Meta:
unique_together = (("sport", "yid"),)
Si le code suivant est exécuté et un joueur avec ce sport/Yid existe déjà dans la base de données, l'enregistrement de ce joueur est supprimé et le nouveau record du joueur est inséré:
for (sport, yid, first, last, team) in NBA_PLAYERS:
player = Player(sport=sport, yid=yid, first=first, last=last, team=team)
player.save()
le problème majeur est que l'identifiant autogenerated du nouvel enregistrement est différent de celui id dans l'enregistrement supprimé et d'autres classes qui utilisent Player comme une clé étrangère référencée cet enregistrement avec l'ancien ID.
appels SQL semblent fonctionner correctement:
mysql> insert into swap_player (sport, yid, first, last, team) values ('mlb', 1234, 'Joel', 'Zumaya', 'det');
ERROR 1062 (23000): Duplicate entry 'mlb-1234' for key 2
Voici l'instruction CREATE appel TABLE de Django:
CREATE TABLE `swap_player` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`sport` varchar(3) NOT NULL,
`yid` integer NOT NULL,
`first` varchar(30) NOT NULL,
`last` varchar(30) NOT NULL,
`team` varchar(3) NOT NULL,
UNIQUE (`sport`, `yid`)
)
;
L'erreur ne manque que si la fonction de sauvegarde() est lancé par un action sur une page Web (HttpRequest). Si je lance la fonction save() à partir de la ligne de commande python, je reçois l'erreur correcte:
>>>
>>> p = Player(sport='mlb', yid=1234, first='Joel', last='Zumaya', team='det')
>>> p.save()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/dave/Development/django_trunk/django/db/models/base.py", line 328, in save
self.save_base(force_insert=force_insert, force_update=force_update)
File "/Users/dave/Development/django_trunk/django/db/models/base.py", line 400, in save_base
result = manager._insert(values, return_id=update_pk)
File "/Users/dave/Development/django_trunk/django/db/models/manager.py", line 138, in _insert
return insert_query(self.model, values, **kwargs)
File "/Users/dave/Development/django_trunk/django/db/models/query.py", line 894, in insert_query
return query.execute_sql(return_id)
File "/Users/dave/Development/django_trunk/django/db/models/sql/subqueries.py", line 309, in execute_sql
cursor = super(InsertQuery, self).execute_sql(None)
File "/Users/dave/Development/django_trunk/django/db/models/sql/query.py", line 1756, in execute_sql
cursor.execute(sql, params)
File "/Users/dave/Development/django_trunk/django/db/backends/util.py", line 19, in execute
return self.cursor.execute(sql, params)
File "/Users/dave/Development/django_trunk/django/db/backends/mysql/base.py", line 83, in execute
return self.cursor.execute(query, args)
File "build/bdist.macosx-10.5-i386/egg/MySQLdb/cursors.py", line 166, in execute
File "build/bdist.macosx-10.5-i386/egg/MySQLdb/connections.py", line 35, in defaulterrorhandler
_mysql_exceptions.IntegrityError: (1062, "Duplicate entry 'mlb-1234' for key 2")
>>> connection.queries
[{'time': '0.000', 'sql': u'INSERT INTO `swap_player` (`sport`, `yid`, `first`, `last`, `team`) VALUES (mlb, 1234, Joel, Zumaya, det)'}]
>>>
>>>
Comment puis-je obtenir la méthode save() à l'erreur si un enregistrement avec le même sport/Yid déjà existe?
Je voudrais savoir que je peux compter sur l'expression unique_together, donc je voudrais éviter d'écraser la méthode save. –