Opened 3 months ago

Last modified 3 months ago

#36466 assigned Cleanup/optimization

Relax check E042 preventing including stored generated fields in composite primary keys

Reported by: David Sanders Owned by: David Sanders
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Currently E042 prevents including GeneratedField in a CompositePrimaryKey.

Postgres & MySQL are both fine with including stored generated columns in primary keys, including when foreign keys reference these pks. Postgres (18) & MySQL both reject the inclusion of virtual generated columns.

SQLite doesn't allow generated columns altogether: https://www.sqlite.org/gencol.html#limitations

I don't have an Oracle instance to test with.

Django should not get in the way of a valid database operations for vendors that do support a feature. I realise that --skip-checks can be passed in but then we'd be bypassing other useful checks for the lifetime of a codebase.

Personally I believe we should remove the generated columns part of E042 altogether as the user will find out the mistake soon enough when the database complains during migration.

Another option may be to just only check for virtual generated columns.

Forum thread: https://forum.djangoproject.com/t/can-we-relax-the-restriction-e042-on-including-generated-fields-in-composite-pks/41438

Change History (11)

comment:1 by David Sanders, 3 months ago

Component: UncategorizedDatabase layer (models, ORM)

comment:2 by Simon Charette, 3 months ago

Triage Stage: UnreviewedAccepted

Accepting on the basis that we should do something here.

Whether we should

  1. Remove the check altogether for GeneratedField
  2. Remove the check for GeneratedField(db_persist=False)
  3. Add a feature flag supports_stored_generated_field_pk and base check of it

is up for debate but given we have a whole section on _Database limitations_ in the GeneratedField docs it seems like 1. is the option that makes the most sense.

comment:3 by David Sanders, 3 months ago

For 2 I think you mean db_persist=True 😉

But yeah I just noticed that option 1. actually is inline with this:

    pk = GeneratedField(primary_key=True, ...)

There's no check for this but it will work as long as db_persist=True for mysql & pg, but will fail for sqlite.

Last edited 3 months ago by David Sanders (previous) (diff)

comment:4 by David Sanders, 3 months ago

Has patch: set

comment:5 by Sarah Boyce, 3 months ago

Owner: set to David Sanders
Status: newassigned

comment:6 by Sarah Boyce, 3 months ago

Needs documentation: set

comment:7 by Sarah Boyce, 3 months ago

Needs documentation: unset

comment:8 by Sarah Boyce, 3 months ago

Triage Stage: AcceptedReady for checkin

comment:9 by Sarah Boyce, 3 months ago

Version: dev5.2

comment:10 by Sarah Boyce, 3 months ago

Patch needs improvement: set
Triage Stage: Ready for checkinAccepted

comment:11 by Sarah Boyce, 3 months ago

Version: 5.2dev

Given #36472, the restriction (while can be harsh) does make some sense and can be relaxed once #36472 is resolved. Hence, I don't plan to backport to 5.2

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