Deelnemingen en subqueries
Om de ene tafel naar de andere te voegen om ook gerelateerde modellen te laden, kunt u de volgende methode gebruiken.
-
select_related(related: Union[List, str]) -> QuerySet -
select_all(follow: bool = True) -> QuerySet -
prefetch_related(related: Union[List, str]) -> QuerySet -
model
- Model.load () methode
-
Query instellen Agent
-
QuerysetProxy.select_related(related: Union[List, str])werkwijze QuerysetProxy.select_all(follow: bool=True)werkwijzeQuerysetProxy.prefetch_related(related: Union[List, str])werkwijze
Selecteer relevant
select_related(related: Union[List, str]) -> QuerySet
Hiermee kunnen gerelateerde modellen vooraf worden opgehaald tijdens dezelfde query.
Bij het gebruik van select\ _ lated wordt altijd slechts één query uitgevoerd tegen de database, wat betekent dat een (soms complexe) join wordt gegenereerd en later geneste modellen worden verwerkt in Python.
Gebruik de naam van de buitenlandse sleutel om het relevante model te verkrijgen.
Gebruik dubbele onderstrepingstekens tussen namen om gerelateerde modelrelaties te koppelen.
!!!Opmerking Als u uit Django komt, houd er dan rekening mee dat ormarselect\ _ lated in Django anders is dan - >, u kunt slechts één relatietype selecteren, terwijl u in ormar gerelateerd kunt selecteren, tegenover buitenlandse sleutel in buitenlandse sleutelrelaties (dus virtuele automatisch gegenereerde sleutels) En het veld ManyToMany (dus alle relaties in de huidige versie).
!!!Tip Om te bepalen welke modelvelden zijn geselecteerd, gebruikt u de velden () en behalve\ _ velden () QuerySet methoden.
!!!Tip Gebruik de methode order\ _ by () om de volgorde van modellen (master of geneste) te bepalen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
U kunt een string of een lijst met strings (of een lijst met velden / velden) opgeven.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
Het veld Many2Many gedraagt zich precies hetzelfde, waar u de naam van het veld Many2Many kunt invoeren en het uiteindelijke model voor u kunt ophalen.
!!!WAARSCHUWING Als u het ForeignKey-veld tijdens alle zoekopdrachten instelt op niet-nullable (en daarom vereist), worden niet-nullable-modellen automatisch vooraf opgehaald, zelfs als u ze niet opneemt in de select\ _ lated.
!!!Merk op dat alle methoden die geen rijen retourneren expliciet een QuerySet-instantie retourneren, zodat u ze aan elkaar kunt koppelen
1 2 3 | |
Alles selecteren
select_all(follow: bool = False) -> QuerySet
Standaard worden er geen relaties geladen wanneer u all () selecteert, en nogmaals, wanneer u select\ _ lated () gebruikt, moet u expliciet alle relaties specificeren die moeten worden geladen. Dit kan omslachtig zijn als u ook geneste relaties wilt opnemen.
Daarom is select\ _ all () geïntroduceerd, dus alle relaties van het model worden standaard geladen (in tegenstelling tot de all () methode).
Standaard worden alleen modellen toegevoegd die direct gerelateerd zijn aan het bovenliggende model (van waaruit de query wordt uitgevoerd).
Als u follow = True instelt, worden ook gerelateerde modellen van gerelateerde modellen toegevoegd.
!!!Info om niet vast te komen te zitten in een oneindige lus, omdat het gerelateerde model ook een relatie onderhoudt met het bovenliggende model dat toegang heeft tot de modelset.
1 2 3 4 | |
Voorbeelddata zijn als volgt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
Om alle bedrijven met alle vestigingen en adressen te kiezen, hoeft u alleen maar te informeren:
1 2 3 4 | |
Natuurlijk is het in dit geval heel eenvoudig om expliciete relatienamen uit te geven in select\ _ lated, maar de voordelen van select\ _ all () worden duidelijk wanneer je meerdere relaties hebt.
Als Bedrijf bijvoorbeeld 3 relaties heeft en alle 3 relaties hun eigen 3 relaties hebben, moet u 9 relatiereeksen uitgeven om\ _ lated te selecteren en selecteert u\ _ all () kan de relatienaam niet wijzigen.
!!!Merk op dat u select\ _ all () kunt koppelen aan andere QuerySet-methoden zoals filter, exclude\ _ fields, etc. Om een relatie uit te sluiten, gebruikt u de aanroep met uitzondering van\ _ velden () met de (ook geneste) naam van de relatie om uit te sluiten.
prefetch correlatie
prefetch_related(related: Union[List, str]) -> QuerySet
Het is toegestaan om gerelateerde modellen vooraf op te halen tijdens query 's, maar in plaats van\ _ lated te selecteren, wordt elk volgend model opgehaald in een afzonderlijke databasequery.
Met prefetch\ _ lated voert elk model één query uit tegen de database, wat betekent dat u meerdere query 's achter elkaar zult uitvoeren.
Gebruik de naam van de buitenlandse sleutel om het relevante model te verkrijgen.
Gebruik dubbele onderstrepingstekens tussen namen om gerelateerde modelrelaties te koppelen.
!!!Tip Om te bepalen welke modelvelden zijn geselecteerd, gebruikt u de velden () en behalve\ _ velden () QuerySet methoden.
!!!Tip Gebruik de methode order\ _ by () om de volgorde van modellen (master of geneste) te bepalen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
U kunt een string of een lijst met strings
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
Het veld Many2Many gedraagt zich precies hetzelfde, waar u de naam van het veld Many2Many kunt invoeren en het uiteindelijke model voor u kunt ophalen.
!!!-waarschuwing: als u het ForeignKey-veld tijdens alle zoekopdrachten instelt op niet-nullable (en daarom vereist), worden niet-nullable-modellen automatisch vooraf opgehaald, zelfs als u ze niet opneemt in de select\ _ lated.
!!!Merk op dat alle methoden die geen rijen retourneren expliciet een QuerySet-instantie retourneren, zodat u ze aan elkaar kunt koppelen
1 2 3 | |
Selecteer correlatie versus prefetch correlatie
Welke van - > select\ _ lated of prefetch\ _ lated moet je gebruiken?
Nou, het hangt echt af van je gegevens. Het beste antwoord is om het zelf uit te proberen en te zien welke sneller / beter presteert binnen je systeembeperkingen.
Wat te onthouden:
prestaties
Aantal query 's: select\ _ lated voert altijd één query uit tegen de database, terwijl prefetch\ _ lated meerdere query 's uitvoert. Query (I / O) bewerkingen zijn meestal, maar niet noodzakelijk, de langzaamste.
Aantal rijen: Stel dat er 10.000 objecten zijn in tabel A, elk object heeft 3 onderliggende objecten in tabel B en vervolgens heeft elk object in tabel B 2 onderliggende objecten in tabel C. Als volgt:
1 2 3 4 5 6 7 8 9 10 11 | |
Dit betekent dat select\ _ lated altijd 60.000 rijen retourneert (10 000*3*2), later gecomprimeerd tot 10 000 modellen.
Hoeveel regels retourneren prefetch\ _ lated?
Nou, het hangt ervan af, als elk van de modellen B en C uniek is, dan retourneert het 10.000 rijen in de eerste query en 30.000 rijen in de tweede query (3 subitems van A in tabel B) Elk van deze is uniek) en 60.000 rijen (elk kind in tabel B is uniek). De 2 kinderen van model B in tabel C zijn uniek in de derde vraag).
In dit geval lijkt select\ _ lated een betere keuze, het zal niet alleen een query uitvoeren in vergelijking met 3 prefetches\ _ lated, maar het zal 60 retourneren in vergelijking met 100 000 prefetches\ _ lated (10 + 30 + 60k) 000 lijnen.
Maar wat als elk model A exact dezelfde drie model Bs heeft en elk model C exact hetzelfde model C? Select\ _ lated geeft nog steeds 60.000 rijen terug, terwijl prefetch\ _ lated 10.000 rijen retourneert voor model A, 3 rijen voor model B en 2 rijen voor model C. Dus een totaal van 10.006 rijen. Nu, afhankelijk van de structuur van het model (dat wil zeggen, als het een lange Text () veld, enz.), prefetch\ _ lated kan sneller zijn, hoewel het moet uitvoeren drie afzonderlijke query 's in plaats van één.
Geheugen
Ormar behoudt geen regedit voor geladen modellen.
Dit betekent dat u in het hierboven geselecteerde\ _ lated voorbeeld altijd 10.000 modellen A, 30.000 modellen B heeft (zelfs als het aantal unieke rijen in de database 3 is - select\ _ lated processing genereert een nieuwe voor elk bovenliggend model Submodel). En 60 000 modellen C.
Als rijen 1, 10, 100, enz. hetzelfde model B delen en u een van hen bijwerkt, worden de resterende rijen met hetzelfde kind niet onmiddellijk bijgewerkt. Als u uw wijzigingen in de database opslaat, zijn de wijzigingen alleen beschikbaar na het opnieuw laden (elk onderliggende item afzonderlijk laden of de hele query opnieuw laden). Dit betekent dat select\ _ lated meer geheugen zal gebruiken omdat elk onderliggende object wordt geïnstantieerd als een nieuw object
- Hij gebruikte duidelijk zijn eigen ruimte.
!!!Houd er rekening mee dat dit in toekomstige releases kan veranderen als we besluiten caching te introduceren.
Waarschuwing: standaard zijn alle kinderen (of gebeurtenissen waarbij hetzelfde model meer dan tweemaal wordt geladen) volledig afzonderlijke en afzonderlijke Python-objecten, ook al vertegenwoordigen ze dezelfde rij in de database.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
In plaats daarvan wordt met prefetch\ _ lated elk uniek onderscheidend kindmodel slechts één keer geïnstantieerd en wordt hetzelfde kindmodel gedeeld met alle oudermodellen. Dit betekent dat in het prefetch\ _ lated voorbeeld hierboven, als er 3 verschillende modellen zijn in tabel B en 2 verschillende modellen in tabel C, slechts 5 subnested modellen worden gedeeld tussen alle Model A-instanties. Dit betekent ook dat als u een eigenschap bijwerkt, alle bovenliggende objecten die eigenschap bijwerken omdat ze hetzelfde onderliggende object delen.
model werkwijze
Elk modelexemplaar heeft een set methoden om zichzelf op te slaan, bij te werken of te laden.
lading
U kunt een ForeignKey-gerelateerd model laden door de load () -methode aan te roepen.
Load () kan worden gebruikt om het model uit de database te vernieuwen als het door een ander proces is gewijzigd.
!!!Tip Lees meer over de load () methode in de modelmethode
QuerysetProxy methode
Wanneer u rechtstreeks toegang krijgt tot de relevante ManyToMany-velden en ReverseForeignKey, wordt een lijst met gerelateerde modellen geretourneerd.
Maar het toont ook een subset van de QuerySet API, zodat u rechtstreeks vanuit het bovenliggende model kunt filteren, maken, gerelateerde modellen kunt selecteren, enz.
Selecteer relevant
Precies hetzelfde als de select\ _ lated-functie hierboven, maar u kunt het gerelateerde object van het andere uiteinde van de relatie halen.
Ga
Alles selecteren
Precies hetzelfde als de select\ _ all-functie hierboven, maar u kunt het gerelateerde object aan de andere kant van de relatie ophalen.
Ga
prefetch correlatie
Precies hetzelfde als de prefetch\ _ lated-functie hierboven, maar u kunt gerelateerde objecten ophalen aan de andere kant van de relatie.
Ga