Notes
Updating UUIDField on MariaDB to Django 5
Updating from Django 4 to Django 5 comes with an incompatible change to how
Django UUIDField
s are stored in MariaDB databases - in Django 4, Django
would store UUIDField
s as char(32)
types but in Django 5, Django would
store UUIDField
s as uuid
types. However, the Django 5 upgrade notes are
incomplete. Following
the directions on a nontrivial Django project, it’s still likely that
you’ll get database errors like
django.db.utils.OperationalError: (4078, "Cannot cast 'int' as 'uuid' in assignment of test_database.table_column.id")
and errors from fitting 36-character UUID strings into 32-character database
fields.
In order to fix this problem, I found that it’s better to convert char(32)
MariaDB fields into uuid
fields first before migrating to Django 5. That
way, there are fewer changes during the update. In order to do so,
While still on Django 4, replace
django.models.UUIDField
with a uuid field using auuid
database type with:# app/models.py from django.db import models class RealUUIDField(models.UUIDField): def db_type(self, connection): return "uuid" class Model(models.Model): id = RealUUIDField(primary_key=True, default=uuid.uuid4, editable=False) # Formerly: # id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
Explicitly declare older migrations on the uuid field as a
char(36)
field. Note that this needs to bechar(36)
because Django will attempt to store UUIDs with dashes ('06cb5e67-467f-4675-91f3-ca466bcee805'
instead of'06cb5e67467f467591f3ca466bcee805'
). In migration files, replacemodels.UUIDField
with:# app/migrations/0001_migration.py class Char36UUIDField(models.UUIDField): def db_type(self, connection): return "char(36)" class Migration(migrations.Migration): operations = [ migrations.CreateModel( name='Model', fields=[ ('id', Char36UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), # Formerly: # ('id', Char36UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ], ), ]
Run
./manage.py makemigrations
to generate a migration that will convert the database column from achar(32)
to auuid
type.Install the
django==5.0
pip package. Fix any other incompatibilities.Replace
RealUUIDField
back tomodels.UUIDField
.