PostgreSQL-specifika databasbegränsningar¶
PostgreSQL stöder ytterligare dataintegritetsbegränsningar tillgängliga från modulen django.contrib.postgres.constraints. De läggs till i modellen Meta.constraints alternativ.
Uteslutningsbegränsning¶
- class ExclusionConstraint(*, name, expressions, index_type=None, condition=None, deferrable=None, include=None, violation_error_code=None, violation_error_message=None)[source]¶
Skapar en uteslutningsbegränsning i databasen. Internt implementerar PostgreSQL uteslutningsbegränsningar med hjälp av index. Standardindextypen är GiST. För att använda dem måste du aktivera btree_gist-tillägget på PostgreSQL. Du kan installera den med hjälp av
BtreeGistExtensionmigreringsoperation.Om du försöker infoga en ny rad som står i konflikt med en befintlig rad, uppstår ett
IntegrityError. På samma sätt när en uppdatering står i konflikt med en befintlig rad.Begränsningar för uteslutning kontrolleras under modellvalidering.
namn¶
- ExclusionConstraint.name¶
uttryck¶
- ExclusionConstraint.expressions¶
En iterabel med 2-tuples. Det första elementet är ett uttryck eller en sträng. Det andra elementet är en SQL-operator som representeras som en sträng. För att undvika skrivfel kan du använda RangeOperators som mappar operatörerna med strängar. Till exempel:
expressions = [
("timespan", RangeOperators.ADJACENT_TO),
(F("room"), RangeOperators.EQUAL),
]
Begränsningar för operatörer.
Endast kommutativa operatorer kan användas i uteslutningsbegränsningar.
Uttrycket OpClass() kan användas för att ange en anpassad operatorklass för begränsningsuttrycken. Till exempel:
expressions = [
(OpClass("circle", name="circle_ops"), RangeOperators.OVERLAPS),
]
skapar en uteslutningsbegränsning på circle med hjälp av circle_ops.
index_typ¶
- ExclusionConstraint.index_type¶
The index type of the constraint. Accepted values are GiST, Hash, or
SPGiST. Matching is case insensitive. If not provided, the default index
type is GIST.
Support for exclusion constraints using Hash indexes was added.
villkor¶
- ExclusionConstraint.condition¶
Ett Q-objekt som anger villkoret för att begränsa en begränsning till en delmängd av rader. Till exempel:, condition=Q(cancelled=False).
Dessa villkor har samma databasrestriktioner som django.db.models.Index.condition.
deferrable¶
- ExclusionConstraint.deferrable¶
Ange denna parameter för att skapa en uppskjutbar uteslutningsbegränsning. Accepterade värden är Deferrable.DEFERRED eller Deferrable.IMMEDIATE. Till exempel:
from django.contrib.postgres.constraints import ExclusionConstraint
from django.contrib.postgres.fields import RangeOperators
from django.db.models import Deferrable
ExclusionConstraint(
name="exclude_overlapping_deferred",
expressions=[
("timespan", RangeOperators.OVERLAPS),
],
deferrable=Deferrable.DEFERRED,
)
Som standard är begränsningar inte uppskjutna. En uppskjuten begränsning kommer inte att verkställas förrän i slutet av transaktionen. En omedelbar begränsning kommer att verkställas omedelbart efter varje kommando.
Varning
Uppskjutna uteslutningsbegränsningar kan leda till en ”prestandaförlust” <https://www.postgresql.org/docs/current/sql-createtable.html#id-1.9.3.85.9.4>`_.
inkludera¶
- ExclusionConstraint.include¶
En lista eller tupel med namnen på de fält som ska ingå i det täckande uteslutningsvillkoret som icke-nyckelkolumner. Detta gör det möjligt att använda skanningar med enbart index för frågor som endast väljer inkluderade fält (include) och endast filtrerar efter indexerade fält (expressions).
include is supported for GiST and SP-GiST indexes.
Felkod för överträdelse¶
- ExclusionConstraint.violation_error_code¶
Den felkod som används när ValidationError uppstår under modellvalidering. Standardvärdet är None.
avvikelse_felmeddelande¶
Det felmeddelande som används när ValidationError uppstår under modellvalidering. Standardvärdet är BaseConstraint.violation_error_message.
Exempel¶
Följande exempel begränsar överlappande bokningar i samma rum, utan att ta hänsyn till avbokade bokningar:
from django.contrib.postgres.constraints import ExclusionConstraint
from django.contrib.postgres.fields import DateTimeRangeField, RangeOperators
from django.db import models
from django.db.models import Q
class Room(models.Model):
number = models.IntegerField()
class Reservation(models.Model):
room = models.ForeignKey("Room", on_delete=models.CASCADE)
timespan = DateTimeRangeField()
cancelled = models.BooleanField(default=False)
class Meta:
constraints = [
ExclusionConstraint(
name="exclude_overlapping_reservations",
expressions=[
("timespan", RangeOperators.OVERLAPS),
("room", RangeOperators.EQUAL),
],
condition=Q(cancelled=False),
),
]
Om din modell definierar ett intervall med två fält, istället för de ursprungliga PostgreSQL-intervalltyperna, bör du skriva ett uttryck som använder motsvarande funktion (t.ex. `` TsTzRange() ) och använda avgränsarna för fältet. Oftast kommer avgränsarna att vara ``'[)', vilket innebär att den nedre gränsen är inkluderande och den övre gränsen är exkluderande. Du kan använda RangeBoundary som tillhandahåller en uttrycksmappning för intervallgränserna. Till exempel:
from django.contrib.postgres.constraints import ExclusionConstraint
from django.contrib.postgres.fields import (
DateTimeRangeField,
RangeBoundary,
RangeOperators,
)
from django.db import models
from django.db.models import Func, Q
class TsTzRange(Func):
function = "TSTZRANGE"
output_field = DateTimeRangeField()
class Reservation(models.Model):
room = models.ForeignKey("Room", on_delete=models.CASCADE)
start = models.DateTimeField()
end = models.DateTimeField()
cancelled = models.BooleanField(default=False)
class Meta:
constraints = [
ExclusionConstraint(
name="exclude_overlapping_reservations",
expressions=[
(
TsTzRange("start", "end", RangeBoundary()),
RangeOperators.OVERLAPS,
),
("room", RangeOperators.EQUAL),
],
condition=Q(cancelled=False),
),
]