Ответ 1
В Django теперь встроен BigAutoField, если вы используете Django 1.10:
https://docs.djangoproject.com/en/1.10/ref/models/fields/#bigautofield
В настоящее время я строил проект, который включает в себя много коллективного интеллекта. Каждый пользователь, посещающий веб-сайт, получает уникальный профиль, и их данные позже используются для расчета наилучших совпадений для себя и других пользователей.
По умолчанию Django создает поле INT (11) id
для обработки первичных ключей моделей. Я обеспокоен тем, что это очень быстро переполнено (то есть ~ 2.4b устройств, посещающих страницу без предварительной настройки cookie). Как я могу изменить его для представления как BIGINT в MySQL и long() внутри самого Django?
Я обнаружил, что могу сделать следующее (http://docs.djangoproject.com/en/dev/ref/models/fields/#bigintegerfield):
class MyProfile(models.Model):
id = BigIntegerField(primary_key=True)
Но есть ли способ сделать это автоинкремент, как обычные поля id
? Кроме того, могу ли я сделать это без знака, чтобы получить больше места для заполнения?
Спасибо!
В Django теперь встроен BigAutoField, если вы используете Django 1.10:
https://docs.djangoproject.com/en/1.10/ref/models/fields/#bigautofield
Вдохновленный lfagundes, но с небольшой, но важной коррекцией:
class BigAutoField(fields.AutoField):
def db_type(self, connection): # pylint: disable=W0621
if 'mysql' in connection.__class__.__module__:
return 'bigint AUTO_INCREMENT'
return super(BigAutoField, self).db_type(connection)
add_introspection_rules([], [r"^a\.b\.c\.BigAutoField"])
Обратите внимание, что вместо расширения BigIntegerField я расширяю AutoField. Это важное различие. С помощью AutoField Django будет извлекать AUTO INCREMENTed id из базы данных, тогда как BigInteger не будет.
Одна из проблем при переходе с BigIntegerField на AutoField заключалась в литье данных в int в AutoField.
Уведомление от Django AutoField:
def to_python(self, value):
if value is None:
return value
try:
return int(value)
except (TypeError, ValueError):
msg = self.error_messages['invalid'] % str(value)
raise exceptions.ValidationError(msg)
и
def get_prep_value(self, value):
if value is None:
return None
return int(value)
Оказывается, это нормально, как проверено в оболочке python:
>>> l2 = 99999999999999999999999999999
>>> type(l2)
<type 'long'>
>>> int(l2)
99999999999999999999999999999L
>>> type(l2)
<type 'long'>
>>> type(int(l2))
<type 'long'>
Другими словами, приведение к int не приведет к усечению числа и не изменяет базовый тип.
ПРИМЕЧАНИЕ. Этот ответ изменен, согласно коду Ларри. Предыдущее решение расширенных полей .BigIntegerField, но лучше расширять поля .AutoField
У меня была та же проблема и решена с помощью следующего кода:
from django.db.models import fields
from south.modelsinspector import add_introspection_rules
class BigAutoField(fields.AutoField):
def db_type(self, connection):
if 'mysql' in connection.__class__.__module__:
return 'bigint AUTO_INCREMENT'
return super(BigAutoField, self).db_type(connection)
add_introspection_rules([], ["^MYAPP\.fields\.BigAutoField"])
По-видимому, это прекрасно работает с южными миграциями.
После этого вы можете изменить таблицу. Это может быть лучшим решением.
Как указано выше, вы можете впоследствии изменить таблицу. Это хорошее решение.
Чтобы сделать это без забвения, вы можете создать модуль управления в своем пакете приложений и использовать сигнал post_syncdb.
https://docs.djangoproject.com/en/dev/ref/signals/#post-syncdb
Это может привести к сбою django-admin.py. Но это все еще лучшая альтернатива, которую я знаю.
У меня также была та же проблема. Похоже, что нет поддержки для автоматических полей BigInteger в django.
Я попытался создать какое-то настраиваемое поле BigIntegerAutoField, но у меня возникла проблема с южной миграционной системой (юг не мог создать последовательность для моего поля).
Попробовав несколько разных подходов, я решил следовать совету Мэттью и изменить таблицу (например, ALTER TABLE table_name ALTER COLUMN id TYPE bigint;
в postgre)
Было бы здорово иметь решение, поддерживаемое django (например, встроенным BigIntegerAutoField) и югом.