﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
24611	Manager update with object instance having UUID as PK fails	Jay Wineinger	nobody	"I'm using UUIDs for the primary keys of some models. Other models relate to those via FK. I ran into an issue today when trying to do a RelatedModel.objects.update(fk=instance_with_uuid_pk), where SQLite failed with 

{{{
Traceback (most recent call last):
  File ""/src/django/tests/update/tests.py"", line 154, in test_update_uuid_fk_with_model_instance
    UUIDRelation.objects.update(relation=self.u1)
  File ""/src/django/django/db/models/manager.py"", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File ""/src/django/django/db/models/query.py"", line 619, in update
    rows = query.get_compiler(self.db).execute_sql(CURSOR)
  File ""/src/django/django/db/models/sql/compiler.py"", line 1056, in execute_sql
    cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
  File ""/src/django/django/db/models/sql/compiler.py"", line 835, in execute_sql
    cursor.execute(sql, params)
  File ""/src/django/django/db/backends/utils.py"", line 64, in execute
    return self.cursor.execute(sql, params)
  File ""/src/django/django/db/utils.py"", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File ""/src/django/django/utils/six.py"", line 658, in reraise
    raise value.with_traceback(tb)
  File ""/src/django/django/db/backends/utils.py"", line 64, in execute
    return self.cursor.execute(sql, params)
  File ""/src/django/django/db/backends/sqlite3/base.py"", line 318, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.InterfaceError: Error binding parameter 0 - probably unsupported type.
}}}

Examining the SQLite table showed a CHAR32 column for the UUID and FK fields, which seems appropriate since SQLite doesn't have a UUID column like postgres. Then I traced execution of the query and found that the params being sent to SQLite was still a UUID, not the hex representation.

Inserting the primary models and related models works fine, so it seems to be an issue with updates. It looks like the SQLUpdateCompiler calls [https://github.com/django/django/blob/dc27f3ee0c3eb9bb17d6cb764788eeaf73a371d7/django/db/models/sql/compiler.py#L1015 prepare_database_save(field)] when a model instance is give as the query value.  That [https://github.com/django/django/blob/dc27f3ee0c3eb9bb17d6cb764788eeaf73a371d7/django/db/models/base.py#L881 just returns the value of the related field], which is just a UUID in this case. This is passed along for execution, where SQLite pukes.

However, if you pass a UUID as the value (not a model instance), field.get_db_prep_save is called which will convert the UUID to its hex value if the DB doesn't support native UUIDs. Thus, updates given a raw UUID work fine.

So it seems like all that needs to change is that we need to call field.get_db_prep_save on the value returned from val.prepare_database_save. I've attached a patch that does this."	Bug	closed	Database layer (models, ORM)	dev	Release blocker	fixed			Accepted	1	0	0	0	0	0
