我在models.py中使用以下类:
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"),)
如果运行以下代码并且数据库中已存在具有该sport / yid的播放器,则会删除该播放器的记录并插入新的播放器记录:
for (sport, yid, first, last, team) in NBA_PLAYERS:
player = Player(sport=sport, yid=yid, first=first, last=last, team=team)
player.save()
这个问题的主要问题是新记录的自动生成的id与已删除记录中的id不同,而其他使用Player作为外键的类引用具有旧id的记录。
SQL调用似乎正常工作:
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
以下是来自Django的CREATE TABLE调用:
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`)
)
;
只有在网页上的操作(HttpRequest)启动了save()函数时,才会丢失错误。如果我从python命令行运行save()函数,那么我得到正确的错误:
>>>
>>> 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)'}]
>>>
>>>
如果已存在具有相同sport / yid的记录,如何让save()方法出错?
答案 0 :(得分:0)
您可以覆盖Player:save()方法。具有如下的东西。我不熟悉unique_together的属性,知道你遇到的是否表明了一个bug。
def save(self, *args, **kwargs):
try:
Player.objects.get(yid = self.yid, sport=self.sport)
raise PlayerObjectExists
except:
return super(Player, self).save(*args, **kwargs)
答案 1 :(得分:0)
听起来你需要take a look at the SQL django orm正在创作。