分配主键整数的范围

时间:2017-01-08 00:51:00

标签: django postgresql django-models primary-key-design

给定自动递增主键整数(1到32767)和RangeB(32768到2147483647)的RangeA。如果条件为true,则使用在RangeA中指定的主键保存对象,否则将其保存在RangeB中。

admin(me)将是保存到RangeA的唯一用户。如果上述情况不可能:如果Django总是保存在RangeB中并且需要进入shell以保存在RangeA中,那么它将不理想但仍然可用。

如何使用Django和Postgres完成这项工作?

1 个答案:

答案 0 :(得分:1)

很可能。首先是更改模型,使其不使用标准AutoField作为主键

class MyModel(models.Model):
    id  = models.IntegerField(primary_key=True)

然后你需要连接到postgresql并创建两个不同的序列。

CREATE SEQUENCE small START 1;
CREATE SEQUENCE big START 32768;

您可以考虑编辑django迁移(使用RunSQL指令)来创建创建这些,而不是在PSQL控制台中输入。

下一步是覆盖保存方法

def save(self,*args, **kwargs)
    if not self.id :
        cursor = connection.cursor()
        if small condition:
            cursor.execute("select nextval('small')")
        else:
            cursor.execute("select nextval('big')")

        self.id = cursor.fetchone()[0]

    super(MyModel,self).save(*args,**kwargs)

覆盖save方法的替代方法是创建一个postgresql BEFORE INSERT Trigger。获得nextval的往返行程并不昂贵,但如果这是一个问题,那么创建触发器就是选择的选择。在这种情况下,你不需要超越save方法,但你必须在触发器中实现相同的逻辑。