Zum Inhalt

Verbindungen und Untersuchen.

Um eine Tabelle mit einer anderen Tabelle zu verbinden, damit auch das zugehörige Modell geladen werden kann, verwenden Sie die folgenden Methoden.

  • select_related(related: Union[List, str]) -> QuerySet

  • select_all(follow: bool = True) -> QuerySet

  • prefetch_related(related: Union[List, str]) -> QuerySet

  • Das Modell

    • Die Load ()-Methode
    • Frage an den Gruppenleiter

    • QuerysetProxy.select_related(related: Union[List, str]) Die Methode

    • QuerysetProxy.select_all(follow: bool=True) Die Methode
    • QuerysetProxy.prefetch_related(related: Union[List, str]) Die Methode

Auswahl betrifft.

select_related(related: Union[List, str]) -> QuerySet

Ermöglicht das Vornehmen relevanter Modelle während der gleichen Abfrage.

Wenn Sie select_lated verwenden, führen Sie immer nur eine Abfrage in Ihrer Datenbank aus, was bedeutet, dass eine (manchmal komplizierte) Verbindung generiert wird, die später mit verschachtelten Modellen in Python verarbeitet wird.

Um das verwandte Modell abzurufen, verwenden Sie den Fremdschlüsselnamen.

Um die zugehörigen Modellbeziehungen zu verknüpfen, verwenden Sie einen doppelten Unterstrich zwischen den Namen.

!!!Hinweis Wenn Sie von django kommen, beachten Sie, dass ormarselect_lated in django im Gegensatz zu-> nur einen einzelnen Beziehungstyp auswählen kann, während Sie in ormar Korrelationen, die Kehrseite des Fremdschlüssels (daher automatisch virtuell generierte Schlüssel) und das Feld ManyToMany (und daher alle Beziehungen der aktuellen Version) über Fremdschlüsselbeziehungen hinweg auswählen können.

!!!tip Um zu steuern, welche Modellfelder ausgewählt werden, verwenden Sie die QuerySet-Methoden fields () und except_fields ().

!!!tip Um die Reihenfolge der Modelle (Haupt-oder geschachtelte Modelle) zu steuern, verwenden Sie die order_by ()-Methode.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Klasse Album (ormar. model):
    ormar_config = base_ormar_config. copy ()(= Grundeinheit von ormar_config. copy)

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    name: str = ormar. String (max_length = 100)[Bearbeiten | Quelltext bearbeiten]
    is_best_seller: bool = ormar. Boolean (default = False)[Bearbeiten | Quelltext bearbeiten]

Klasse Track (ormar. Modell):
    ormar_config = base_ormar_config. copy ()(= Grundeinheit von Ormar_config. copy)

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    Album: Optional [Album]= ormar. ForeignKey (Album)[Bearbeiten | Quelltext bearbeiten]
    title : str = ormar . String (max _ length = 100)
    position : int = ormar . Integer () oder
    play _ count : int = ormar . Integer (nullable = true) [ Bearbeiten | Quelltext bearbeiten ]


Der Django Stil
Ausstellung = AwaitAlbum.objects.select_ related (" tracks ") . alle ()

Der Python-Stil
Ausstellung = AwaitAlbum.objects.select_ related (Album . tracks) . all () (Übersetzung)

Album mit allen Kolumnen Tracks

Sie können eine Zeichenfolge oder eine Zeichenfolgenliste (oder eine Feld -/Feldliste) angeben

 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
Schulklasse (ormar . Modell) :
    ormar _ config = base _ ormar _ config . copy (tablename = " Schulklassen ")

    id : int = ormar . Integer (primary _ key = true) (nicht bekannt)
    name : str = ormar . String (max _ length = 100)
    department : Optional [ Abteilung ] = ormar . ForeignKey (Abteilung , nullable = False)


Klasse Kategorie (ormar . Modell) :
    ormar _ config = base _ ormar _ config . copy (tablename = " Kategorien ")

    id : int = ormar . Integer (primary _ key = true) (nicht bekannt)
    name : str = ormar . String (max _ length = 100) [ Bearbeiten | Quelltext bearbeiten ]


Klasse Schüler (ormar .
    ormar _ config = base _ ormar _ config . copy () (= Grundeinheit von Ormar _ config . copy)

    id : int = ormar . Integer (primary _ key = true) (nicht bekannt)
    name : str = ormar . String (max _ length = 100) [ Bearbeiten | Quelltext bearbeiten ]
    schoolclass : Optional [ Schulklasse ] = ormar . ForeignKey
    Kategorie : Optional [ Category ] = ormar . ForeignKey (Category , nullable = True)


Klasse Lehrer (ormar . Modell) :
    ormar _ config = base _ ormar _ config . copy () (= Grundeinheit von ormar _ config . copy)

    id : int = ormar . Integer (primary _ key = true) (nicht bekannt)
    name : str = ormar . String (max _ length = 100) [ Bearbeiten | Quelltext bearbeiten ]
    schoolclass : Optional [ Schulklasse ] = ormar . ForeignKey
    Kategorie : Optional [ Category ] = ormar . ForeignKey (Category , nullable = True)


Der Django Stil
Klassen = AwaitSchoolClass.objects.selectim Zusammenhang (
    [ " Lehrer _ Kategorie " , " Schüler " ]) . all ()

Der Python-Style
Klassen = AwaitSchoolClass.objects.selectim Zusammenhang (
    Schulklasse , Lehrer , Kategorie , Schulklasse , Schüler ]) .

# will return Klassen mit Lehrern und Lehrern Kategorien
Wie gut sind die Schüler

Das Many2Many-Feld verhält sich genau gleich , in das Sie den Namen des Many2Many-Felds eingeben und das endgültige Modell für Sie abrufen können .

!!!Warnung Wenn Sie das Feld ForeignKey während aller Abfragen auf nicht leer setzen (und daher erforderlich) , werden Modelle , die nicht leer sein können , automatisch vorgeholt , auch wenn Sie sie nicht in select \ _ lated einschließen .

!!!Beachten Sie , dass alle Methoden , die keine Zeile zurückgeben , explizit eine Instanz von QuerySet zurückgeben , sodass Sie sie miteinander verknüpfen können .

1
2
3
So Operationen wie `filter()`,`select_related()`,`limit()` und `offset()` etc. kann chained werden .

Etwas Ähnliches `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`

Alle wählen wählen

select_all(follow: bool = False) -> QuerySet

Standardmäßig werden keine Beziehungen geladen , wenn Sie all () auswählen , und ebenso müssen Sie explizit alle Beziehungen angeben , die geladen werden sollen , wenn Sie select \ _ lated () verwenden , was sehr umständlich sein kann , wenn Sie auch verschachtelte Beziehungen einbeziehen möchten .

Aus diesem Grund wurde select \ _ all () eingeführt , so dass standardmäßig alle Beziehungen des Modells geladen werden (im Gegensatz zur all () - Methode) .

Standardmäßig werden nur Modelle hinzugefügt , die direkt mit dem übergeordneten Modell verknüpft sind (von dem aus Sie die Abfrage ausführen) .

Wenn Sie follow = true setzen , werden auch verwandte Modelle für verwandte Modelle hinzugefügt .

!!!Um nicht in eine Endlosschleife zu fallen , behalten die relationalen Modelle auch ihre Beziehung zum Elternmodell bei , das auf die Modellmenge zugreift .

1
2
3
4
Diese Art von besuchten Modellen , die unerwünscht sind , wird geladen , aber die Last tut es nicht
Folgen Sie dem Modell A-> Model B-> Model C-> Model A-> Model X
Es wird das zweite Modell A laden, aber es wird nie in das Model X folgen.
Die Beziehungen dieser Art müssen manuell geladen werden.

Die Stichtage lauten wie folgt:

 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
Die Datei ist in der Datei "_(
    database = databases. Database (DATABASE_URL, force_rollback = true) oder
    metadata = sqlalchemy. metadata (), oder
)


Klasse Adresse (ormar. Model):
    ormar_config = base_ormar_config. copy (tablename ="addresses")

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    string = ormar. String (max_length = 100, nullable = False)
    Anzahl: int = ormar. Integer (nullable = False)
    post_code: str = ormar. String (max_length = 20, nullable = False)



Klasse Branch (ormar. Modell):
    ormar_config = base_ormar_config. copy (tablename ="Branchen")

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    String (max_length = 100, nullable = False)(max_length = 100, nullable = False)(keine Zeichenfolge)
    address = ormar. ForeignKey (Address) oder


Klasse (ormar. model):
    ormar_config = base_ormar_config. copy (tablename ="Unternehmen")

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    String (max_length = 100, nullable = False, name ="Firmenname")
    founded: int = ormar. Integer (nullable = true)[Bearbeiten | Quelltext bearbeiten]
    branches = ormar. manyToMany (Branch)(mehrere)

Um alle Unternehmen mit allen Niederlassungen und Adressen auszuwählen, fragen Sie einfach nach:

1
2
3
4
Unternehmen = AwaitCompany.objects.selectAlle (folgt = true)

Was gleichwertig ist :
Wirtschaft = AwaitCompany.objects.select_ related ('branches _ _ address') . alle () ()

Natürlich ist es in diesem Fall sehr einfach , einen expliziten relationalen Namen in select \ _ lated auszugeben , aber die Vorteile von select \ _ all () werden sich zeigen , wenn Sie mehr als eine Beziehung haben .

Beispiel : Wenn Company 3 Beziehungen hat und alle drei ihre eigenen 3 Beziehungen haben , müssen Sie 9 Beziehungszeichenfolgen an select \ _ lated ausgeben , und select \ _ all () kann den Namen der Beziehung nicht ändern .

!!!Beachten Sie, dass Sie select_all () mit anderen QuerySet-Methoden verknüpfen können, z. B. filter, exclude_fields usw. Um eine Beziehung auszuschließen, verwenden Sie den Aufruf except_fields () mit dem Namen der Beziehung, die Sie ausschließen möchten (der ebenfalls verschachtelt ist).

Vorausschauende relevant

prefetch_related(related: Union[List, str]) -> QuerySet

Ermöglicht das Pre-Abrufen relationaler Modelle während einer Abfrage - im Gegensatz zu select \ _ lated wird jedoch jedes nachfolgende Modell in einer separaten Datenbankabfrage erworben .

Bei Verwendung von prefetch \ _ lated führt jedes Modell eine Abfrage für die Datenbank aus , d . h . Sie führen mehrere Abfragen nacheinander aus .

Um das verwandte Modell zu erhalten , verwenden Sie den Fremdschlüsselnamen .

Um die zugehörigen Modellbeziehungen zu verknüpfen , verwenden Sie einen doppelten Unterstrich zwischen den Namen .

!!!tip Um zu steuern , welche Modellfelder ausgewählt werden , verwenden Sie die QuerySet-Methoden fields () und except \ _ fields () .

!!!tip Um die Reihenfolge der Modelle (Haupt - oder geschachtelte Modelle) zu steuern , verwenden Sie die order \ _ by () - Methode .

 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
Klasse Album (ormar . Modell) :
    ormar _ config = base _ ormar _ config . copy () (= Grundeinheit von ormar _ config . copy)

    id : int = ormar . Integer (primary _ key = true) (nicht bekannt)
    name : str = ormar . String (max _ length = 100)
    is _ best _ seller : bool = ormar . Boolean (default = False) [ Bearbeiten | Quelltext bearbeiten ]

Klasse Track (ormar . Modell) :
    ormar _ config = base _ ormar _ config . copy () (= Grundeinheit von ormar _ config . copy)

    id : int = ormar . Integer (primary _ key = true) (nicht bekannt)
    Album : Optional [ Album ] = ormar . ForeignKey (Album) [ Bearbeiten | Quelltext bearbeiten ]
    title : str = ormar . String (max _ length = 100)
    position : int = ormar . Integer () oder
    play _ count : int = ormar . Integer (nullable = true) [ Bearbeiten | Quelltext bearbeiten ]


Der Django Stil
Album = await Album. objects. prefetch_related ("tracks"). all ()[Bearbeiten | Quelltext bearbeiten]

Der Python-Stil
Album = await Album. objects. prefetch_related (Album. tracks). all ()[Bearbeiten | Quelltext bearbeiten]


#Will return Album wird alle Kolumnen Tracks

Sie können einen String oder eine Zeichenkette Liste erstellen.

 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
Schulklasse (ormar. Modell):
    ormar_config = base_ormar_config. copy (tablename ="Schulklassen")

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    name: str = ormar. String (max_length = 100)
    department: Optional [Abteilung]= ormar. ForeignKey (Abteilung, nullable = False)


Klasse (ormar. Modell):
    ormar_config = base_ormar_config. copy (tablename ="Kategorien")

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    name: str = ormar. String (max_length = 100)[Bearbeiten | Quelltext bearbeiten]


Klasse Schüler (ormar.
    ormar_config = base_ormar_config. copy ()(= Grundeinheit von ormar_config. copy)

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    name: str = ormar. String (max_length = 100)[Bearbeiten | Quelltext bearbeiten]
    schoolclass: Optional [Schulklasse]= ormar. ForeignKey
    Kategorie: Optional [Category]= ormar. ForeignKey (Category, nullable = True)


Klasse Lehrer (ormar. Modell):
    ormar_config = base_ormar_config. copy ()(= Grundeinheit von ormar_config. copy)

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    name: str = ormar. String (max_length = 100)[Bearbeiten | Quelltext bearbeiten]
    schoolclass: Optional [Schulklasse]= ormar. ForeignKey
    Kategorie: Optional [Category]= ormar. ForeignKey (Category, nullable = True)


Der Django Stil
=
    ["Lehrer_Kategorie","Schüler"]). all ()

Der Python-Style
=
    Schulklasse, Lehrer, Kategorie, Schulklasse, Schüler]).
#will return Klassen mit Lehrern und Lehrern Kategorien
Wie gut sind die Schüler

Das Many2Many-Feld verhält sich genau gleich, in dem Sie den Namen des Many2Many-Felds eingeben und das endgültige Modell für Sie abrufen können.

!!!Warnung Wenn Sie das Feld ForeignKey während aller Abfragen nicht auf Null setzen (und daher erforderlich), werden Modelle, die nicht leer sein können, automatisch vorbestellt, auch wenn Sie sie nicht in select_lated einschließen.

!!!Beachten Sie, dass alle Methoden, die keine Zeile zurückgeben, explizit eine Instanz von QuerySet zurückgeben, sodass Sie sie miteinander verknüpfen können.

1
2
3
So Operationen wie `filter()`,`select_related()`,`limit()` und `offset()` etc. kann chained werden.

Etwas Ähnliches `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`

Die Auswahl ist mit der Vorauswahl verknüpft.

Welche von den Optionen-> select_lated oder prefetch_lated sollten Sie verwenden?

Nun, die beste Antwort, die wirklich von Ihren Daten abhängt, ist, sie selbst auszuprobieren und zu sehen, welche unter den Einschränkungen Ihres Systems schneller/besser funktioniert.

Was zu erinnern ist:

demonstrieren.

Anzahl der Abfragen: select_lated führt immer eine einzige Abfrage für die Datenbank aus, prefetch_lated führt mehrere aus In der Regel sind Query (I/O)-Operationen die langsamsten, müssen es aber nicht sein.

Anzahl der Zeilen: Angenommen, eine Tabelle A enthält 10 000 Objekte, jedes Objekt hat 3 untergeordnete Objekte in Tabelle B und jedes Objekt in Tabelle B hat dann 2 untergeordnete Objekte in Tabelle C, wie folgt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
                     Das Model C
                   /
           Das Model B-das Model C
         / 
Das Model A-das Model B-das Model C
       \           \ 
        \            Das Model C
         \
           Das Model B - das Model C
                   \ 
                     Das Model C

Das bedeutet , dass select \ _ lated immer 60.000 Zeilen (10.000 *3 *2) zurückgibt , die später auf 10.000 Modelle komprimiert werden .

Wie viele Zeilen geben prefetch \ _ lated zurück ?

Nun , das hängt davon ab , ob jedes der Modelle B und C eindeutig ist , dann werden 10 000 Zeilen in der ersten Abfrage und 30 000 Zeilen in der zweiten Abfrage zurückgegeben .(Jeder der drei Teilelemente von A in Tabelle B ist eindeutig) , sowie 60 000 Zeilen (jeder Teilschlüssel in Tabelle B ist eindeutig) .

In diesem Fall scheint select \ _ lated eine bessere Option zu sein , da es nicht nur eine Abfrage als 3 prefetch \ _ lated ausführt , sondern auch 60 000 Zeilen im Vergleich zu 100 000 prefetch \ _ lated (10 + 30 + 60k) zurückgibt .

select \ _ lated gibt immer noch 60.000 Zeilen zurück , während prefetch \ _ lated 10.000 Zeilen für Modell A , 3 Zeilen für Modell B und 2 Zeilen für Modell C , also insgesamt 10.006 Zeilen zurückgibt . Nun , abhängig von der Struktur des Modells (d.h. wenn es lange Text () - Felder usw . hat , kann prefetch \ _ lated schneller sein , obwohl es drei separate Abfragen anstelle einer benötigt .

Erinnerung

ormar behält die Registrierung der geladenen Modelle nicht bei .

Das bedeutet , dass Sie im Beispiel select _ lated oben immer über 10 000 Modelle A , 30 000 Modelle B verfügen (auch wenn die Verarbeitung mit 3 - select _ lated nur eine Anzahl Zeilen in der Datenbank ein neues Untermodell für jedes übergeordnete Modell erzeugt) und 60 000 Modelle C .

Wenn Zeile 1 , 10 , 100 usw . dasselbe Modell B verwenden und Sie eines davon aktualisieren , wird der Rest derselben Untereinheit nicht sofort aktualisiert Wenn die Änderungen in der Datenbank gespeichert werden , sind die Änderungen erst nach dem erneuten Laden verfügbar (jedes Unterelement einzeln oder die gesamte Abfrage erneut laden) , was bedeutet , dass select \ _ lated mehr Speicher verwendet , da jedes Unterobjekt als neues Objekt instanziiert wird .

  • Es ist klar , dass wir unseren eigenen Raum nutzen .

!!!Hinweis : Wenn wir uns für die Einführung des Caches entscheiden , könnte sich dies in zukünftigen Versionen ändern .

Standardmäßig sind alle Unterschlüssel (oder Ereignisse , bei denen dasselbe Modell mehr als zweimal geladen wurde) völlig getrennte , verschiedene Python-Objekte , obwohl sie dieselbe Zeile in der Datenbank repräsentieren .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
Sie werden dies als wahr bewerten , wenn sie verglichen werden , so dass im Beispiel oben :

```python
# will return True if child1 of both rows is the same child db row 
row1.child1 == row100.child1

# same here:
model1 = await Model.get(pk=1)
model2 = await Model.get(pk=1) # same pk = same row in db
# will return `True`
model1 == model2
```

but

```python
# will return False (note that id is a python `builtin` function not ormar one).
id(row1.child1) == id(ro100.child1)

# from above - will also return False
id(model1) == id(model2)
```

Im Gegensatz dazu wird mit prefetch _ lated jedes eindeutige , unterschiedliche Untermodell nur einmal instanziiert , und dasselbe Untermodell wird von allen übergeordneten Modellen gemeinsam verwendet , was bedeutet , dass im obigen prefetch _ late-Beispiel , wenn es 3 verschiedene Modelle in Tabelle B und 2 verschiedene Modelle in Tabelle C gibt , nur 5 untergeschachtelte Modelle zwischen allen Model A-Instanzen freigegeben werden . Das bedeutet auch , dass , wenn Sie eine Eigenschaft aktualisieren , alle übergeordneten Objekte diese Eigenschaft aktualisieren , da sie dasselbe untergeordnete Objekt verwenden .

Die Modellmethode

Jede Modellinstanz verfügt über eine Reihe von Methoden zum Speichern , Aktualisieren oder Laden von sich selbst .

Aufladen

Sie können ForeignKey-bezogene Modelle laden , indem Sie die load () - Methode aufrufen .

load () kann verwendet werden , um ein Modell aus der Datenbank zu aktualisieren , wenn es von einem anderen Prozess geändert wird .

!!!tip Lesen Sie mehr über die load () - Methode in Modellmethoden

Die QuerysetProxy Methode

Wenn Sie direkt auf das zugehörige Feld " ManyToMany " und " ReverseForeignKey " zugreifen , wird eine Liste der zugehörigen Modelle zurückgegeben .

Gleichzeitig wird jedoch eine Teilmenge der QuerySet-API verfügbar gemacht, sodass Sie relevante Modelle direkt aus dem übergeordneten Modell filtern, erstellen, auswählen usw. können.

Auswahl betrifft.

Es ist genau das gleiche wie die SELECT_LATED Funktion oben, ermöglicht es Ihnen jedoch, verwandte Objekte vom anderen Ende der Beziehung zu erhalten.

!!!tip Um mehr über QuerysetProxy zu erfahren, besuchen Sie den Abschnitt querysetproxy

Alle wählen wählen

Es ist genau das gleiche wie die SELECT_ALL Funktion oben, ermöglicht es Ihnen jedoch, verwandte Objekte vom anderen Ende der Beziehung zu erhalten.

!!!tip Um mehr über QuerysetProxy zu erfahren, besuchen Sie den Abschnitt querysetproxy

Vorausschauende relevant

Genau wie die oben genannte prefetch_lated-Funktion, aber Sie können verwandte Objekte vom anderen Ende der Beziehung erhalten.

!!!tip Um mehr über QuerysetProxy zu erfahren, besuchen Sie den Abschnitt querysetproxy