Может ли первичный ключ использовать BigInteger в качестве AutoField в Django 1.2.4?

Кажется, что первичный ключ по умолчанию — int. Есть ли способ использовать большое целое число для автополя в качестве первичного ключа?


person zs2020    schedule 29.01.2011    source источник
comment
Я действительно не могу поверить, что Django даже не поддерживает первичный ключ BigInteger по своей сути, как он может конкурировать с другими фреймворками ?? Я думаю, что я должен просто использовать UUID, даже если он не совсем подходит для моей ситуации.   -  person zs2020    schedule 22.02.2011
comment
возможный дубликат поля автоинкремента Django BigInteger в качестве первичного ключа?   -  person FallenAngel    schedule 17.01.2014


Ответы (8)


Я бы посоветовал вам использовать более новый Django. Официальная документация Django сейчас не старше версии 1.3. А 1.3 небезопасна и не поддерживается. Я понимаю, что вопрос был задан более 3 лет назад, но, поскольку принятого ответа до сих пор нет, я попробую.

В Django 1.6.5 вы можете просто сделать это в своей модели:

class MyModel(models.Model):
    id = models.BigIntegerField(unique=True, primary_key=True)

primary_key=True переопределит идентификатор модели по умолчанию. При использовании это поле автоматически увеличивается с каждым новым объектом модели. Это просто работает!

person e.thompsy    schedule 09.09.2014

Я вижу несколько способов реализовать это. В любом случае, вы должны определить свое поле pk.

Прежде всего, просто создайте собственное поле идентификатора и переопределите метод сохранения.

modelname(models.Model):
    # model definition

def save(self):
    self.pkfield = nextIntFucntion()
    super(modelname, self).save()

nextIntFunction() достаточно просто запросить объекты, упорядоченные по id, а затем получить id+1

Я также нашел эту ссылку BigIntegerField и BigAutoField, которая, кажется, решает проблему, но я не проверял ее сам.

person neolaser    schedule 07.02.2011
comment
Юг будет правильно мигрировать. Это не сработает, если вы вручную вводите данные в базу данных (или вне django) - person neolaser; 08.02.2011
comment
nextIntFunction() достаточно проста с запросом объектов, упорядоченных по идентификатору, а затем получить идентификатор + 1... как вы можете гарантировать уникальность, если несколько читателей одновременно увеличивают его на единицу? - person zs2020; 11.02.2011
comment
хм, хороший вопрос. Так как nextInt будет рассчитываться при сохранении, шансы довольно малы... но все же они есть. Расширение идеи, вы можете сохранить таблицу BigIntReference... - person neolaser; 11.02.2011
comment
... или, может быть, Django применяет блокировку при сохранении ... не уверен. Потребуются дополнительные исследования, чтобы уточнить - person neolaser; 11.02.2011
comment
Django НЕ применяет блокировку при сохранении (по крайней мере, не в 1.6). Это состояние гонки, ожидающее провала. Не говоря уже о том, что если у вас достаточно этой модели, чтобы потребовать ключ bigint, вы, вероятно, сохраните их довольно быстро, что только увеличивает вероятность попадания в это условие. С другой стороны, поскольку это первичный ключ, целостность будет обеспечиваться базой данных, поэтому вы можете просто зациклить свой супервызов. - person DylanYoung; 29.07.2016

Я тоже встречал такой же вопрос. Я добавил некоторый код, например

User._meta.has_auto_field = True
User._meta.auto_field = id

И я определяю поле id как BigIntegerField(primary_key=True). После того, как я использую user.Save(), user.id будет иметь свой идентификатор, мне не нужно снова запрашивать. Я думаю, что это работает, но это не красивое решение, поэтому я все еще нахожу хороший способ.

person ZhouQi    schedule 14.12.2011

Начиная с Django 1.10 вы можете использовать BigAutoField, как описано в документация работает точно так же, как AutoField, но это гарантированно подходят числа от 1 до 9223372036854775807.

Таким образом, вы можете использовать его как:

class SomeModel(models.Model):
    id = models.BigAutoField()
    ...
person Henoc Díaz    schedule 07.03.2017

Вы можете взломать Django и изменить автоматические ключи по умолчанию на правильные значения. Проверить:

http://code.djangoproject.com/browser/django/trunk/django/db/backends/mysql/creation.py

from django.conf import settings
from django.db.backends.creation import BaseDatabaseCreation

class DatabaseCreation(BaseDatabaseCreation):
    # This dictionary maps Field objects to their associated MySQL column
    # types, as strings. Column-type strings can contain format strings; they'll
    # be interpolated against the values of Field.__dict__ before being output.
    # If a column type is set to None, it won't be included in the output.
    data_types = {
        'AutoField':         'integer AUTO_INCREMENT',
        'BooleanField':      'bool',
        'CharField':         'varchar(%(max_length)s)',

Вы можете изменить это, используя патч в своем собственном коде:

DatabaseCreation.data_types['AutoField'] = 'bigint AUTO_INCREMENT'

Вам также придется исправить класс AutoField:

http://code.djangoproject.com/browser/django/trunk/django/db/models/fields/__init__.py

(непроверенный код, удачи)

person Dimitry    schedule 08.02.2011
comment
Взлом фреймворка никогда не бывает хорошей идеей. Всегда лучше продлить. - person shangxiao; 06.11.2014
comment
То же самое можно сделать, просто создав модель подкласса AutoBigIntField, чтобы использовать ее в качестве pk по умолчанию и зарегистрировать ее с соответствующим типом данных в бэкэнде. - person DylanYoung; 29.07.2016

http://docs.djangoproject.com/en/dev/topics/db/models/

класс BigIntegerField([**опции])

доступный вариант:

primary_key Если значение равно True, это поле является первичным ключом модели.

И в конце концов вы выполняете южную миграцию: ALTER TABLE mytable MODIFY COLUMN myid BIGINT(20) NOT NULL AUTO_INCREMENT;

person Alexander A.Sosnovskiy    schedule 29.01.2011
comment
Вы уверены, что это автоинкремент?? - person zs2020; 29.01.2011

Вы правы, извините. Необходимый фрагмент находится здесь:

http://djangosnippets.org/snippets/1244/

Позволяет создавать поля bigint (mysql), bigserial (psql) или NUMBER (19) (oracle), которые имеют автоинкремент, установленный с помощью AutoField django, что обеспечивает обновление идентификатора в экземпляре при вызове его сохранения. ()' метод.

Если бы вы только подклассировали IntegerField к BigIntegerField и использовали бы его в качестве первичного ключа, созданный вами экземпляр модели не получил бы атрибут id, установленный при вызове «save()», вместо этого вам пришлось бы запрашивать и загружать экземпляр из БД еще раз, чтобы получить идентификатор.

person Alexander A.Sosnovskiy    schedule 29.01.2011

Эти фрагменты работают. Используйте класс BigAutoField в качестве первичного ключа в вашей модели, и он будет работать без каких-либо взломов.

person notbad.jpeg    schedule 26.07.2013