#35438: Failed to insert an model instance into db that utilizes a UUID as its primary key and incorporates a GeneratedField. -----------------------------------------+------------------------ Reporter: 长孙弘奕 | Owner: nobody Type: Uncategorized | Status: new Component: Uncategorized | Version: 5.0 Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 1 Needs documentation: 0 | Needs tests: 0 Patch needs improvement: 0 | Easy pickings: 0 UI/UX: 0 | -----------------------------------------+------------------------ I have defined a model that employs a UUIDField as its primary key, accompanied by a JSONField and several GeneratedFields, which are intended for indexing the JSONFields. However, when attempting to load data via loaddata from a JSON fixture, the process fails during the execution of the execute_sql method within django/db/models/SQL/compiler.py. The problematic code snippet is as follows:
{{{ def execute_sql(self, returning_fields=None): .... if not self.returning_fields: return [] .... else: cols = [opts.pk.get_col(opts.db_table)] rows = [ ( self.connection.ops.last_insert_id( cursor, opts.db_table, opts.pk.column, ), ) ] converters = self.get_converters(cols) if converters: rows = list(self.apply_converters(rows, converters)) return rows }}} Here, returning_fields comprises GeneratedFields, thereby preventing the method from directly returning an empty list at the outset of its logical execution. Moreover, since the model's primary key is not an AUTO_INCREMENT column (it's a UUID), last_insert_id() erroneously returns 0. This subsequently triggers an error within self.apply_converters(rows, converters) as it attempts to treat 0 as a UUID. To address this issue, the else block logic requires adjustment to accommodate the presence of GeneratedField. Alternatively, within django/db/models/base.py's _save_table method, one could exclude GeneratedField from returning_fields. A modified approach might resemble: {{{ #Original: returning_fields = meta.db_returning_fields returning_fields = [ f for f in meta.db_returning_fields if not f.generated] results = self._do_insert( cls._base_manager, using, fields, returning_fields, raw ) if results: for value, field in zip(results[0], returning_fields): setattr(self, field.attname, value) return updated }}} This adjusted strategy has proven effective in my project, successfully circumventing the aforementioned issues without introducing new problems. -- Ticket URL: <https://code.djangoproject.com/ticket/35438> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/0107018f56b747ec-b2a33923-b834-41c7-92ed-29d5c46232ff-000000%40eu-central-1.amazonses.com.