2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-07-04 06:00:38 +00:00

[db] Fix for UUID fields (#12301)

This commit is contained in:
Oliver
2026-07-04 07:57:55 +10:00
committed by GitHub
parent f656ac7263
commit f93c813bb4
5 changed files with 123 additions and 4 deletions
+29
View File
@@ -1,6 +1,7 @@
"""Custom fields used in InvenTree.""" """Custom fields used in InvenTree."""
import sys import sys
import uuid
from decimal import Decimal from decimal import Decimal
from django import forms from django import forms
@@ -59,6 +60,34 @@ class InvenTreeURLField(models.URLField):
super().__init__(**kwargs) super().__init__(**kwargs)
class InvenTreeUUIDField(models.UUIDField):
"""UUIDField which is always stored as a char(32) column on MySQL / MariaDB.
On MariaDB 10.7+, Django maps UUIDField to the native 'uuid' column type,
and writes 36-character (hyphenated) values to match.
However, databases migrated under older Django / MariaDB versions retain
their original char(32) columns, into which a 36-character value does not fit.
To ensure consistent behavior across all supported database backends,
we force the legacy char(32) storage format on MySQL / MariaDB.
Ref: https://docs.djangoproject.com/en/5.2/releases/5.0/#migrating-existing-uuidfield-on-mariadb-10-7
"""
def db_type(self, connection):
"""Force a char(32) column type on MySQL / MariaDB backends."""
if connection.vendor == 'mysql':
return 'char(32)'
return super().db_type(connection)
def get_db_prep_value(self, value, connection, prepared=False):
"""Store values in 32-character hex format on MySQL / MariaDB backends."""
value = super().get_db_prep_value(value, connection, prepared)
if connection.vendor == 'mysql' and isinstance(value, uuid.UUID):
value = value.hex
return value
def money_kwargs(**kwargs): def money_kwargs(**kwargs):
"""Returns the database settings for MoneyFields.""" """Returns the database settings for MoneyFields."""
from common.currency import currency_code_mappings from common.currency import currency_code_mappings
@@ -0,0 +1,59 @@
"""Migration to store UUID primary keys as char(32) on MySQL / MariaDB.
On MariaDB 10.7+, Django 5.x creates UUIDField columns with the native 'uuid'
type and writes 36-character (hyphenated) values. Databases migrated under older
Django / MariaDB versions retain char(32) columns, into which the new values
do not fit.
See: https://github.com/inventree/InvenTree/issues/12270
"""
import uuid
from django.db import migrations
import InvenTree.fields
class Migration(migrations.Migration):
dependencies = [('common', '0045_projectcode_active')]
operations = [
migrations.AlterField(
model_name='emailmessage',
name='global_id',
field=InvenTree.fields.InvenTreeUUIDField(
default=uuid.uuid4,
editable=False,
help_text='Unique identifier for this message',
primary_key=True,
serialize=False,
unique=True,
verbose_name='Global ID',
),
),
migrations.AlterField(
model_name='emailthread',
name='global_id',
field=InvenTree.fields.InvenTreeUUIDField(
default=uuid.uuid4,
editable=False,
help_text='Unique identifier for this thread',
primary_key=True,
serialize=False,
verbose_name='Global ID',
),
),
migrations.AlterField(
model_name='webhookmessage',
name='message_id',
field=InvenTree.fields.InvenTreeUUIDField(
default=uuid.uuid4,
editable=False,
help_text='Unique identifier for this message',
primary_key=True,
serialize=False,
verbose_name='Message ID',
),
),
]
+3 -3
View File
@@ -1584,7 +1584,7 @@ class WebhookMessage(models.Model):
worked_on: Was the work on this message finished? worked_on: Was the work on this message finished?
""" """
message_id = models.UUIDField( message_id = InvenTree.fields.InvenTreeUUIDField(
verbose_name=_('Message ID'), verbose_name=_('Message ID'),
help_text=_('Unique identifier for this message'), help_text=_('Unique identifier for this message'),
primary_key=True, primary_key=True,
@@ -3266,7 +3266,7 @@ class EmailMessage(models.Model):
TRACK_READ = 'track_read', _('Track Read') TRACK_READ = 'track_read', _('Track Read')
TRACK_CLICK = 'track_click', _('Track Click') TRACK_CLICK = 'track_click', _('Track Click')
global_id = models.UUIDField( global_id = InvenTree.fields.InvenTreeUUIDField(
verbose_name=_('Global ID'), verbose_name=_('Global ID'),
help_text=_('Unique identifier for this message'), help_text=_('Unique identifier for this message'),
primary_key=True, primary_key=True,
@@ -3374,7 +3374,7 @@ class EmailThread(InvenTree.models.InvenTreeMetadataModel):
blank=True, blank=True,
help_text=_('Unique key for this thread (used to identify the thread)'), help_text=_('Unique key for this thread (used to identify the thread)'),
) )
global_id = models.UUIDField( global_id = InvenTree.fields.InvenTreeUUIDField(
verbose_name=_('Global ID'), verbose_name=_('Global ID'),
help_text=_('Unique identifier for this thread'), help_text=_('Unique identifier for this thread'),
primary_key=True, primary_key=True,
@@ -0,0 +1,28 @@
"""Migration to store MachineConfig UUID primary keys as char(32) on MySQL / MariaDB.
On MariaDB 10.7+, Django 5.x writes 36-character (hyphenated) UUID values,
but databases migrated under older Django / MariaDB versions retain char(32)
columns, causing machine creation to fail with "Data too long for column 'id'".
See: https://github.com/inventree/InvenTree/issues/12270
"""
import uuid
from django.db import migrations
import InvenTree.fields
class Migration(migrations.Migration):
dependencies = [('machine', '0001_initial')]
operations = [
migrations.AlterField(
model_name='machineconfig',
name='id',
field=InvenTree.fields.InvenTreeUUIDField(
default=uuid.uuid4, editable=False, primary_key=True, serialize=False
),
),
]
+4 -1
View File
@@ -10,6 +10,7 @@ from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
import common.models import common.models
import InvenTree.fields
from machine import registry from machine import registry
from machine.machine_type import BaseMachineType from machine.machine_type import BaseMachineType
@@ -17,7 +18,9 @@ from machine.machine_type import BaseMachineType
class MachineConfig(models.Model): class MachineConfig(models.Model):
"""A Machine objects represents a physical machine.""" """A Machine objects represents a physical machine."""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) id = InvenTree.fields.InvenTreeUUIDField(
primary_key=True, default=uuid.uuid4, editable=False
)
name = models.CharField( name = models.CharField(
unique=True, unique=True,