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: