Django with MSSQL Server – GUID Type is maped as char(32) not uniqueidentifier

I would like an app that can easily use different databases. Currently, I’m using SQLite and MSSQL, switching between them via a config file. I noticed that the following field could be quite important from a performance standpoint:

user_guid = models.UUIDField(
    default=uuid.uuid4,  
    editable=False,      
    unique=True,          
    null=False,          
    blank=False,         
    db_index=True        
)

In MSSQL, the field is mapped as char(32), and I have mixed feelings about that. Over time, I might switch to PostgreSQL, but as I mentioned before, I’m not entirely comfortable using char(32) instead of uniqueidentifier.

This is because it is specified like a char(32) [GitHub]:

class DatabaseWrapper(BaseDatabaseWrapper):
    # …
    data_types = {
        # …
        'UUIDField': 'char(32)',
    }
    # …

Changing it is also not easy: MSSQL has no native UUID field, one can use a BINARY(16), but there is nothing that accepts a UUID itself. The UUIDField converts a value to a value for the database with [GitHub]:

class UUIDField(Field):
    # …

    def get_db_prep_value(self, value, connection, prepared=False):
        if value is None:
            return None
        if not isinstance(value, uuid.UUID):
            value = self.to_python(value)

        if connection.features.has_native_uuid_field:
            return value
        return value.hex

    # …

so either it works with the UUID object itself, or with the .hex of a UUID field, so what a VARCHAR essentially stores.

Databases that have a native UUID field, like PostgreSQL, use that type.

This is because it is specified like a char(32) [GitHub]:

class DatabaseWrapper(BaseDatabaseWrapper):
    # …
    data_types = {
        # …
        'UUIDField': 'char(32)',
    }
    # …

Changing it is also not easy: MSSQL has no native UUID field, one can use a BINARY(16), but there is nothing that accepts a UUID itself. The UUIDField converts a value to a value for the database with [GitHub]:

class UUIDField(Field):
    # …

    def get_db_prep_value(self, value, connection, prepared=False):
        if value is None:
            return None
        if not isinstance(value, uuid.UUID):
            value = self.to_python(value)

        if connection.features.has_native_uuid_field:
            return value
        return value.hex

    # …

so either it works with the UUID object itself, or with the .hex of a UUID field, so what a VARCHAR essentially stores.

Databases that have a native UUID field, like PostgreSQL, use that type.

pyodbc had no support for conversion from uniqueidentifer/SQL_GUID to UUID at the time of package creation (pyodbc native support issue)

as following change was implemented, writing uniqueidentifer instead of char(32) implementation was straight forward

That being said lack of interest in using MSSQL with Django and therefore lack of official support is probably reason why this is not implemented as part of package

Update:

Back to Top