Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have an unsigned AutoField?

I want a primary key for my model to be unsigned. Therefore I do something like this:

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

This gets me an UNSIGNED column in the resulting MySQL table, which I want. However, I believe I will not get the automatic assigning to id each time I create a new object, will I? This seems to require the use of AutoField instead. Problem is, AutoField is signed. Is there a way to create an unsigned AutoField?

like image 446
dragonroot Avatar asked Aug 29 '13 14:08

dragonroot


1 Answers

The actual type of the field is specified in the backend. In the case of MySQL, the backend is django.db.backends.mysql. This extract from django/db/backends/mysql/creation.py shows this translation:

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)',
        ...

To change that, you should either monkey-patch this dict doing:

from django.db.backends.mysql.creation import DatabaseCreation
DatabaseCreation.data_types['AutoField'] = 'integer UNSIGNED AUTO_INCREMENT'

Or you create your own class, so you won't mess up with the other AutoFields:

from django.db.models.fields import AutoField
class UnsignedAutoField(AutoField):
    def get_internal_type(self):
        return 'UnsignedAutoField'

from django.db.backends.mysql.creation import DatabaseCreation
DatabaseCreation.data_types['UnsignedAutoField'] = 'integer UNSIGNED AUTO_INCREMENT'

And then create your own PKs:

id = UnsignedAutoField()

As it descends from AutoField, it will inherit all of its behavior.

like image 59
augustomen Avatar answered Sep 29 '22 04:09

augustomen