django-pghistory
django-pghistory copied to clipboard
Events queryset fails for custom model PKs
If a tracked model has a custom private key field, which has a different database representation to the instance value, the queryset for pghistory.models.Event
fails:
Example error:
django.db.utils.DataError: invalid input syntax for type uuid: "acc-uHsnqvKUT9SsDb6xe8i2zi"
LINE 62: WHERE _event.pgh_obj_id = 'acc-uHsnqvKUT9SsDb6...
This happens because of the bug in EventsQueryCompiler._get_where_clause
, which uses PK values directly stringified in:
if isinstance(rows, models.QuerySet) or len(rows) > 1:
opt = "IN"
# TODO: Use a subquery
pks = "','".join(f"{o.pk}" for o in rows)
pks = f"('{pks}')" # <--- here
else:
opt = "="
pks = f"'{rows[0].pk}'" # <--- and here
Both o.pk
and rows[0].pk
values should be compiled correctly with tracked_model._meta.pk.get_db_prep_value
. Also, it's safe to mogrify
the value.
For example, for rows[0].pk
the code should be this:
with self.connection.cursor() as cursor:
value = rows[0]._meta.pk.get_db_prep_value(rows[0].pk, self.connection)
pks = cursor.mogrify("%s", [value]).decode("utf-8")