简体   繁体   English

分配主键整数范围

[英]Allocate ranges of primary key integers

Given RangeA of auto-incrementing primary key integers (1 to 32767) and RangeB (32768 to 2147483647).给定自动递增主键整数的 RangeA(1 到 32767)和 RangeB(32768 到 2147483647)。 If a condition is true, save an object with a primary key assigned in RangeA, else save it in RangeB.如果条件为真,则将主键保存在 RangeA 中的对象,否则将其保存在 RangeB 中。

The admin (me) would be the only user saving to RangeA.管理员(我)将是唯一保存到 RangeA 的用户。 If the above is not possible: It would be not ideal but still usable if Django always saved in RangeB and it required going into shell to save in RangeA.如果以上不可行:如果 Django 总是保存在 RangeB 中并且需要进入 shell 以保存在 RangeA 中,这将不理想但仍然可用。

How can this be done using Django and Postgres?如何使用 Django 和 Postgres 做到这一点?

Quite possible.很有可能。 First thing is to change your model so that it doesn't use the standard AutoField as the primary key第一件事是更改您的模型,使其不使用标准 AutoField 作为主键

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

Then you need to connect to postgresql and create two different sequences.然后你需要连接到 postgresql 并创建两个不同的序列。

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

Instead of typing that into the PSQL console, you might also consider editing the django migration (using a RunSQL directive) to create create these.除了在 PSQL 控制台中输入它,您还可以考虑编辑 django 迁移(使用 RunSQL 指令)来创建这些。

Next step is to override the save method下一步是覆盖保存方法

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)

Alternative to overriding the save method is to create a postgresql BEFORE INSERT Trigger.覆盖 save 方法的替代方法是创建一个 postgresql BEFORE INSERT 触发器。 The round trip to get the nextval isn't very costly but if this is a concern creating a trigger is the option to choose.获得 nextval 的往返费用不是很高,但如果这是一个问题,创建触发器是选择的选项。 In that case you don't need to over ride the save method but you have to implement the same logic inside the trigger.在这种情况下,您不需要覆盖 save 方法,但您必须在触发器内实现相同的逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM