Opened 6 years ago

Closed 6 years ago

#29913 closed Bug (duplicate)

prefetch_related() crash with foreign key to model with non-abstract base class and UUID pk

Reported by: Alexei Komissarov Owned by: nobody
Component: Database layer (models, ORM) Version: 2.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have this models:

class Vehicle(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_date = models.DateTimeField(verbose_name="Created date", auto_now_add=True)

class Car(Vehicle):
    Name = models.CharField("Name", max_length=255)    

class Item(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    car = models.ForeignKey(
        Car, related_name="items", on_delete=models.PROTECT)

I develop with SQLite db which doesn't support UUID columns.
When I query Items I get item with car_id - hex value. I debuged application and found that in DatabaseOperations.get_db_converters() internal_type for column car is OneToOneField and it didn't have self.convert_uuidfield_value of course.

This issue is reason of exception in function prefetch_related:

Exception Type:	KeyError
Exception Value:	
('27156424-a53d-4b4e-a909-04ceba6c65e1',)
Exception Location:	C:\Source\InMeta.py\inmeta\venv\lib\site-packages\django\db\models\fields\related_descriptors.py in get_prefetch_queryset, line 611
}}}}

Change History (3)

comment:1 by Tim Graham, 6 years ago

Please give the queryset that crashes.

comment:2 by Alexei Komissarov, 6 years ago

Models:

import uuid

from django.db import models


class Vehicle(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_date = models.DateTimeField(verbose_name="Created date", auto_now_add=True)


class CarVehicle(Vehicle):
    name = models.CharField("Name", max_length=255)


class Item(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    car = models.ForeignKey(
        CarVehicle, related_name="items", on_delete=models.PROTECT)

Test:

from django.test import TestCase

from testbed.models import CarVehicle, Item


class CrashTest(TestCase):
    def setUp(self):
        car = CarVehicle.objects.create(name="test")
        Item.objects.create(car=car)

    def test_error(self):
        cars = CarVehicle.objects.all().prefetch_related("items")
        for car in cars:
            print(len(list(car.items.all())))

Exception:

ERROR: test_error (tests.CrashTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Source\InMeta.py\inmeta\testbed\tests.py", line 13, in test_error
    for car in cars:
  File "C:\Source\InMeta.py\inmeta\venv\lib\site-packages\django\db\models\query.py", line 268, in __iter__
    self._fetch_all()
  File "C:\Source\InMeta.py\inmeta\venv\lib\site-packages\django\db\models\query.py", line 1188, in _fetch_all
    self._prefetch_related_objects()
  File "C:\Source\InMeta.py\inmeta\venv\lib\site-packages\django\db\models\query.py", line 723, in _prefetch_related_objects
    prefetch_related_objects(self._result_cache, *self._prefetch_related_lookups)
  File "C:\Source\InMeta.py\inmeta\venv\lib\site-packages\django\db\models\query.py", line 1569, in prefetch_related_objects
    obj_list, additional_lookups = prefetch_one_level(obj_list, prefetcher, lookup, level)
  File "C:\Source\InMeta.py\inmeta\venv\lib\site-packages\django\db\models\query.py", line 1682, in prefetch_one_level
    prefetcher.get_prefetch_queryset(instances, lookup.get_current_queryset(level)))
  File "C:\Source\InMeta.py\inmeta\venv\lib\site-packages\django\db\models\fields\related_descriptors.py", line 611, in get_prefetch_queryset
    instance = instances_dict[rel_obj_attr(rel_obj)]
KeyError: ('de3dacc26c974743b3fe91ae2cb291ab',)

comment:3 by Tim Graham, 6 years ago

Resolution: duplicate
Status: newclosed
Summary: Issue with ForeignKey to model with non-abstract base class and UUID-pkprefetch_related() crash with foreign key to model with non-abstract base class and UUID pk

This is fixed in Django's master branch (Django 2.2) by 5e3463f6bcec818431f0e1f4649d6a5bd944c459 (#27595).

Note: See TracTickets for help on using tickets.
Back to Top