Django:如何正确删除数据库记录以防止主键重用?

时间:2014-09-28 03:30:46

标签: sql django sqlite primary-key

我的期望是,即使我删除了包含主键pk=k的记录,然后创建了新记录,这条新记录也至少会获得pk=k+1

环境:Python 2.7.8 + Django 1.6.5 +默认sqlite3 enginie

我的/repeatId/models.py

from django.db import models

# Create your models here.
class Foo(models.Model):
    name = models.CharField(max_length=30)
    def __unicode__(self):
        return self.name

manage.py shell互动:

>>> from repeatId.models import Foo
>>> Foo.objects.all().count()
0
>>> Foo.objects.create(name='first')
<Foo: first>
>>> Foo.objects.all().count()
1
>>> foo = Foo.objects.all()[0]
>>> foo.id
1
>>> Foo.objects.get(id=1).delete()          <--- deleting initial obj with id=1
>>> Foo.objects.all().count()
0
>>> Foo.objects.create(name='second')
<Foo: second>
>>> Foo.objects.all().count()
1
>>> foo = Foo.objects.all()[0]
>>> foo.id                                  <--- expected to get id=2, but got id=1
1

2 个答案:

答案 0 :(得分:2)

这是Django中的a bug {1.7}版本中的has been fixed

答案 1 :(得分:0)

创建另一个模型,强制只有一条记录存储foo模型的最后一个使用的pk:

class FooPK(models.Model):
    last_used_foo_pk = models.IntegerField()
    def save(self, *args, **kwargs):
        if self.pk == 1: #force only ONE record to ever be in the db
            super(FooPK, self).save(*args, **kwargs)

覆盖Foo的保存方法以从FooPK获取最后使用的pk,递增它,将其保存到两个模型

class Foo(models.Model):
    ...
    def save(self, *args, **kwargs):
        PKRecord = FooPK.objects.get(pk=1) #FooPK's only object pk will not change, you have forced only the first record to ever 
        new_pk = PKRecord.last_used_foo_pk + 1
        self.pk = new_pk
        super(Foo, self).save(*args, **kwargs)
        PKRecord.last_used_foo_pk = new_pk
        PKRecord.save()