Выделите диапазоны целых чисел первичного ключа

Дан RangeA для автоинкрементных целых чисел первичного ключа (от 1 до 32767) и RangeB (от 32768 до 2147483647). Если условие истинно, сохраните объект с первичным ключом, назначенным в RangeA, иначе сохраните его в RangeB.

Администратор (я) будет единственным пользователем, сохраняющим в RangeA. Если вышеупомянутое невозможно: было бы не идеально, но все же можно было бы использовать, если Django всегда сохранял в RangeB, и для сохранения в RangeA требовалось войти в оболочку.

Как это можно сделать с помощью Django и Postgres?

1 ответ

Решение

Вполне возможно. Прежде всего, измените вашу модель, чтобы она не использовала стандартное AutoField в качестве первичного ключа.

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

Затем вам нужно подключиться к postgresql и создать две разные последовательности.

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

Вместо того, чтобы вводить это в консоли PSQL, вы можете также рассмотреть возможность редактирования миграции django (используя директиву RunSQL), чтобы создать их.

Следующий шаг - переопределить метод сохранения.

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)

Альтернативой переопределению метода сохранения является создание postgresql перед триггером INSERT. В оба конца, чтобы получить nextval не очень дорого, но если это проблема, создание триггера - выбор. В этом случае вам не нужно перегружать метод сохранения, но вы должны реализовать ту же логику внутри триггера.

Другие вопросы по тегам