#36627 closed New feature (wontfix)
Support PostgreSQL 18+ temporal constraints
Reported by: | Adam Johnson | Owned by: | |
---|---|---|---|
Component: | contrib.postgres | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | David Sanders | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
- Release note
- `UNIQUE CONSTRAINT` docs for `WITHOUT OVERLAPS`
- `PRIMARY KEY` docs for `WITHOUT OVERLAPS`
- `FOREIGN KEY` docs for `PERIOD`
PostgreSQL 18 comes with support for "temporal constraints". These allow adding a special modifier to the final column in a unique constraint (WITHOUT OVERLAPS
), primary key (WITHOUT OVERLAPS
), or foreign key (PERIOD
) which turns that column into a kind of "period specifier". This allows enforcing the given constraint is valid only for the range of that period. While the feature is not time-specific, the natural use case is to enforce uniqueness / validness over time, hence the name.
I propose that we add support for this feature in Django's UniqueConstraint
, through some a new expression WithoutOverlaps
in django.contrib.postgres
, which would be used like this:
from django.db import models from django.contrib.postgres.constraints import WithoutOverlaps from django.contrib.postgres.fields import DateTimeRangeField class Booking(models.Model): title = models.TextField() room = models.ForeignKey(Room, on_delete=models.CASCADE) span = DateTimeRangeField() class Meta: constraints = [ models.UniqueConstraint( "room", WithoutOverlaps("span"), name="%(app_label)s_%(class)s_room_span_no_overlaps" ), ]
This could compile down to SQL like UNIQUE (room_id, span WITHOUT OVERLAPS)
.
It may also be possible, but more tricky, to support the other two ways to specify temporal constraints:
- Primary key support would need to modify or subclass
CompositePrimaryKey
to supportWithoutOverlaps
for the final column. - Foreign key support would need to modify or subclass
ForeignObject
, which is still a private API.
Change History (4)
comment:1 by , 3 weeks ago
Type: | Uncategorized → New feature |
---|
comment:2 by , 3 weeks ago
Yes, it seems to be PostgreSQL-only. But the SQL syntax *is* much easier to use, and it would be similarly so within Django models, which should help with adoption of exclusion/temporal constraints.
comment:3 by , 3 weeks ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Thanks all, please continue this discussion at django/new-features. Any level of effort estimate you would have on UniqueConstraint.validate
and Simon's concern about contrib.postgres-specific flavors of UniqueConstraint
would be helpful.
comment:4 by , 3 weeks ago
Cc: | added |
---|
I haven't seen the new-features thread for this? so adding my 2¢ here for now...
I'd love to see temporal features be added to Django, I've been toying with this myself as well.
It should be noted that MariaDB's temporal features are more feature complete and differ slightly as they tend more towards the SQL standard. If we do support temporal features, then I'd strongly urge folks to, at least, be sure to include Maria in design considerations, (otherwise centre design around this owing to the closeness of the standard?)
https://mariadb.com/docs/server/reference/sql-structure/temporal-tables
Note the key difference is the formation of "periods" from date/timestamp columns from which the "without overlaps" keys are formed.
CREATE OR REPLACE TABLE rooms ( room_number INT, guest_name VARCHAR(255), checkin DATE, checkout DATE, PERIOD FOR p(checkin,checkout), UNIQUE (room_number, p WITHOUT OVERLAPS) );
Adam if you want to create the new-feature I'll gladly upvote it
If we are to accept this ticket I suggest we focus it on the
UniqueConstraint
case and then considerCompositePrimaryKey
and foreign support once #35956 lands.The hard part here will likely not be to write the
WithoutOverlaps
expression part but to adjustUniqueConstraint.validate
to honor it without couplingcontrib.postgres
and core.I'll note that
WITHOUT OVERLAPS
is really just SQL sugar over exclusion constraints which we already support viaExclusionConstraint
so I'm not entirely convinced it's worth adding given theUniqueConstraint.validate
complexity it would incur.