#35941: Add composite GenericForeignKey support
-------------------------------------+-------------------------------------
Reporter: Csirmaz Bendegúz | Owner: Csirmaz
| Bendegúz
Type: New feature | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Csirmaz Bendegúz):
* has_patch: 0 => 1
Old description:
> This is a follow up to #373 (''CompositePrimaryKey'').
>
> **Proposal:**
>
> My proposal is to implement ''GenericForeignKey'' support with **JSON**.
>
> 1. `object_id` is a `CharField` (or `TextField`)
> 2. ''CompositePrimaryKey'' is stored as a ''JSON array'' in `object_id`
> 3. JOINs can be achieved with JSON functions (varies per db backend)
>
> **Risks:**
>
> What if someone is using a JSON array as the primary key (but it's not a
> composite primary key)?
> ''Before deserializing the JSON array, we need to check if the content
> type has a composite primary key or not.''
>
> What if the db backend doesn't support JSON functions?
> ''All supported databases support JSON functions.''
>
> **Notes:**
>
> 1. JOINs must work with Unicode characters
> 2. int, date, datetime, uuid, text fields must be supported
> 3. Django admin's `LogEntry` has its own implementation of "generic
> foreign keys". The approach we take with `GenericForeignKey` should also
> apply to `LogEntry`.
>
> Any feedback is appreciated!
New description:
This is a follow up to #373 (''CompositePrimaryKey'').
**Proposal:**
My proposal is to implement ''GenericForeignKey'' support with **JSON**.
1. `object_id` is a `CharField` (or `TextField`)
2. ''CompositePrimaryKey'' is stored as a ''JSON array'' in `object_id`
3. JOINs can be achieved with JSON functions (varies per db backend)
*Joins:*
After some experimentation with JSON functions, I believe the simplest
solution is to construct JOINs like this:
{{{
JOIN ON ((object_id::jsonb)->>0)::integer = id
AND ((object_id::jsonb)->>1)::uuid = uuid
}}}
Casting is a pain point, especially when joining on `DateTimeField`s, as
we need to make sure the two columns are in the same format.
**Risks:**
What if someone is using a JSON array as the primary key (but it's not a
composite primary key)?
''Before deserializing the JSON array, we need to check if the content
type has a composite primary key or not.''
What if the db backend doesn't support JSON functions?
''All supported databases support JSON functions.''
**Notes:**
1. JOINs must work with Unicode characters
2. int, date, datetime, uuid, text fields must be supported
3. Django admin's `LogEntry` has its own implementation of "generic
foreign keys". The approach we take with `GenericForeignKey` should also
apply to `LogEntry`.
Any feedback is appreciated!
--
--
Ticket URL: <https://code.djangoproject.com/ticket/35941#comment:6>
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 [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/010701938635b3f0-a237d1c2-a6a3-4f45-ac78-ff0085a47d36-000000%40eu-central-1.amazonses.com.