Besseres Verständnis der `yield_per ()` Probleme von SQLalchemy

Zitieren SQLalchemy Dokumentation:

Die Query.yield_per () -Methode ist nicht mit den meisten eifrigen Ladeschemata kompatibel, einschließlich Subqueryload und Joinload mit Sammlungen.

Warnun

Verwenden Sie diese Methode mit Vorsicht. Wenn dieselbe Instanz in mehr als einem Zeilenstapel vorhanden ist, werden Änderungen an Attributen durch den Endbenutzer überschrieben.

Insbesondere ist es normalerweise nicht möglich, diese Einstellung für eifrig geladene Sammlungen zu verwenden (d. H. Für Lazy = "Joined" oder "Subquery"), da diese Sammlungen für eine neue Ladung gelöscht werden, wenn sie in einem nachfolgenden Ergebnisstapel auftreten. Beim Laden von Unterabfragen wird das vollständige Ergebnis für alle Zeilen abgerufen, was im Allgemeinen den Zweck von yield_per () außer Kraft setzt.

Beachten Sie auch, dass yield_per () zwar die Ausführungsoption stream_results auf True setzt, dies derzeit jedoch nur von psycopg2-Dialekt verstanden wird, der Ergebnisse mithilfe von serverseitigen Cursorn streamen kann, anstatt alle Zeilen für diese Abfrage vorab zu puffern. Andere DBAPIs puffern alle Zeilen vor, bevor sie verfügbar gemacht werden. Der Speicherverbrauch von unformatierten Datenbankzeilen ist viel geringer als der eines ORM-zugeordneten Objekts, sollte jedoch beim Benchmarking weiterhin berücksichtigt werden.

Ich habe wirklich ein Problem zu verstehen, wieyield_per() funktioniert und was genau ist das Problem bei der Verwendung dieser Methode. Was ist auch der richtige Weg, um diese Probleme zu umgehen und diese Funktion weiterhin für das Durchlaufen einer großen Anzahl von Zeilen zu verwenden?

Ich interessiere mich für alle konstruktiven Informationen, aber hier sind einige Tipps:

Wie kann es mehrere Instanzen derselben Zeile geben? Nur durch Beziehungen (wenn zwei Zeilen der iterierenden Tabelle eine FK zu derselben Zeile in einer anderen Tabelle haben)? Gibt es ein Problem, wenn Sie nicht wissen, dass es passiert, oder wenn Sie nur Attribute zu den Beziehungen lesen? lazy = "verbunden" oder "Unterabfrage" ist nicht möglich, aber warum genau? Beide sind einfach Teile Ihrer Anfrage, bei der Sie @ anrufeyield_per().Wenn sie in einem nachfolgenden Ergebnisstapel gelöscht werden, laden Sie sie einfach erneut. Wo liegt also das Problem? Oder ist das einzige Problem, dass Sie die Änderungen Ihrer Beziehungen verlieren, wenn Sie Änderungen vorgenommen haben?Warum werden beim Laden einer Unterabfrage alle Zeilen abgerufen? Der SQL Server muss möglicherweise eine große Tabelle speichern, aber warum dann nicht einfach das Ergebnis für die gesamte Abfrage stapelweise nacheinander zurückgeben?In einem Beispiel imyield_per() doc q = sess.query(Object).yield_per(100).options(lazyload('*'), joinedload(Object.some_related)) sie deaktivieren eagerload mitlazyload('*') aber behalten Sie eine einzelne verbundene Last. Gibt es eine Möglichkeit, @ noch zu verwendeyield_per() mit eifriger Ladung? Was sind die BedingungenSie sagenpsycopg2 ist das einzige DBAPI, das Stream-Ergebnisse unterstützt. Ist das also das einzige DBAPI, das Sie mit @ verwenden könneyield_per()? So weit ich das versteheyield_per verwendet dascursor.fetchmany() (Beispie) Funktion von DBAPI, die viele von ihnen unterstützt. Und soweit ich das verstehecursor.fetchmany() unterstützt das Abrufen nur eines Teils des Ergebnisses und ruft nicht alles ab (Wenn es alles abrufen würde, warum existiert die Funktion?)Ich habe das Gefühl, dassyield_per() ist absolut sicher (auch bei Eifer), wenn Sie nur Lesezugriff haben (zum Beispiel für Statistiken). Ist das korrekt

Antworten auf die Frage(2)

Ihre Antwort auf die Frage