Django BigInteger auto-increment field as primary key? Django BigInteger auto-increment field as primary key? python python

Django BigInteger auto-increment field as primary key?


Inspired by lfagundes but with a small but important correction:

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"])

Notice instead of extending BigIntegerField, I am extending AutoField. This is an important distinction. With AutoField, Django will retrieve the AUTO INCREMENTed id from the database, whereas BigInteger will not.

One concern when changing from BigIntegerField to AutoField was the casting of the data to an int in AutoField.

Notice from Django's 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)

and

def get_prep_value(self, value):    if value is None:        return None    return int(value)

It turns out this is OK, as verified in a python shell:

>>> l2 = 99999999999999999999999999999>>> type(l2)<type 'long'>>>> int(l2)99999999999999999999999999999L>>> type(l2)<type 'long'>>>> type(int(l2))<type 'long'>

In other words, casting to an int will not truncate the number, nor will it change the underlying type.


NOTE: This answer as modified, according to Larry's code. Previous solution extended fields.BigIntegerField, but better to extend fields.AutoField

I had the same problem and solved with following code:

from django.db.models import fieldsfrom south.modelsinspector import add_introspection_rulesclass 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"])

Apparently this is working fine with south migrations.