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
BtreeGistExtension
migreringsoperation.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¶
Indextypen för begrÀnsningen. Accepterade vÀrden Àr GIST
eller SPGIST
. Matchningen Àr okÀnslig för skiftlÀgesskillnader. Om det inte anges Àr standardindextypen GIST
.
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
stöds för GiST-index. PostgreSQL 14+ stöder ocksÄ include
för SP-GiST-index.
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),
),
]