SQLAlchemy 2.0 Dokumentation
SQLAlchemy Unified Tutorial
- Aufbau der Konnektivität - die Engine
- Arbeiten mit Transaktionen und der DBAPI
- Arbeiten mit Datenbankmetadaten
- Arbeiten mit Daten
- Datenmanipulation mit dem ORM¶
- Arbeiten mit ORM-bezogenen Objekten
- Weitere Lektüre
Projektversionen
- Vorheriger: UPDATE- und DELETE-Anweisungen verwenden
- Nächster: Arbeiten mit ORM-bezogenen Objekten
- Nach oben: Startseite
- Auf dieser Seite
Datenmanipulation mit dem ORM¶
Der vorherige Abschnitt Arbeiten mit Daten konzentrierte sich auf die SQL Expression Language aus Core-Perspektive, um Kontinuität über die wichtigsten SQL-Anweisungskonstrukte hinweg zu bieten. Dieser Abschnitt baut auf dem Lebenszyklus der Session und ihrer Interaktion mit diesen Konstrukten auf.
Voraussetzungsabschnitte - der ORM-fokussierte Teil des Tutorials baut auf zwei früheren ORM-zentrierten Abschnitten dieses Dokuments auf
Ausführung mit einer ORM-Session - führt ein, wie ein ORM
Session-Objekt erstellt wirdVerwendung von ORM-deklarativen Formularen zur Definition von Tabellenmetadaten - hier richten wir unsere ORM-Mappings der
UserundAddressEntitäten einORM-Entitäten und Spalten auswählen - einige Beispiele, wie SELECT-Anweisungen für Entitäten wie
Userausgeführt werden
Einfügen von Zeilen mithilfe des ORM Unit of Work-Musters¶
Bei Verwendung des ORM ist das Session-Objekt für die Konstruktion von Insert-Konstrukten und deren Emission als INSERT-Anweisungen innerhalb der laufenden Transaktion verantwortlich. Die Art und Weise, wie wir die Session dazu anweisen, ist das Hinzufügen von Objekteinträgen; die Session stellt dann sicher, dass diese neuen Einträge bei Bedarf an die Datenbank gesendet werden, was als Flush bezeichnet wird. Der gesamte Prozess, den die Session zum Persistieren von Objekten verwendet, ist als Unit of Work-Muster bekannt.
Instanzen von Klassen repräsentieren Zeilen¶
Während wir im vorherigen Beispiel ein INSERT mit Python-Dictionaries zur Angabe der hinzuzufügenden Daten emittiert haben, verwenden wir mit dem ORM direkt die benutzerdefinierten Python-Klassen, die wir zuvor unter Verwendung von ORM-deklarativen Formularen zur Definition von Tabellenmetadaten definiert haben. Auf Klassenebene dienten die Klassen User und Address als Ort zur Definition des Aussehens der entsprechenden Datenbanktabellen. Diese Klassen dienen auch als erweiterbare Datenobjekte, die wir zur Erstellung und Manipulation von Zeilen innerhalb einer Transaktion verwenden. Im Folgenden erstellen wir zwei User-Objekte, die jeweils eine potenzielle Datenbankzeile darstellen, die eingefügt werden soll.
>>> squidward = User(name="squidward", fullname="Squidward Tentacles")
>>> krabs = User(name="ehkrabs", fullname="Eugene H. Krabs")Wir können diese Objekte mithilfe der Namen der zugeordneten Spalten als Schlüsselwortargumente im Konstruktor erstellen. Dies ist möglich, da die User-Klasse einen automatisch generierten __init__()-Konstruktor enthält, der von der ORM-Zuordnung bereitgestellt wurde, sodass wir jedes Objekt mit Spaltennamen als Schlüssel im Konstruktor erstellen konnten.
Ähnlich wie in unseren Core-Beispielen für Insert haben wir keinen Primärschlüssel (d. h. keinen Eintrag für die id-Spalte) aufgenommen, da wir die Auto-Inkrement-Funktion der Datenbank, in diesem Fall SQLite, nutzen möchten, mit der das ORM ebenfalls integriert ist. Der Wert des id-Attributs der obigen Objekte würde, wenn wir ihn betrachten würden, als None angezeigt werden.
>>> squidward
User(id=None, name='squidward', fullname='Squidward Tentacles')Der Wert None wird von SQLAlchemy bereitgestellt, um anzuzeigen, dass das Attribut noch keinen Wert hat. Von SQLAlchemy zugeordnete Attribute geben in Python immer einen Wert zurück und lösen keine AttributeError aus, wenn sie fehlen, bei der Arbeit mit einem neuen Objekt, dem noch kein Wert zugewiesen wurde.
Derzeit befinden sich unsere beiden obigen Objekte in einem Zustand, der als transient bezeichnet wird - sie sind nicht mit einem Datenbankzustand verknüpft und werden noch keinem Session-Objekt zugeordnet, das INSERT-Anweisungen für sie generieren kann.
Objekte zu einer Session hinzufügen¶
Um den Hinzufügungsprozess Schritt für Schritt zu veranschaulichen, erstellen wir eine Session, ohne einen Kontextmanager zu verwenden (und müssen sie daher später schließen!)
>>> session = Session(engine)Die Objekte werden dann mithilfe der Methode Session.add() zur Session hinzugefügt. Wenn dies aufgerufen wird, befinden sich die Objekte in einem Zustand namens pending und wurden noch nicht eingefügt.
>>> session.add(squidward)
>>> session.add(krabs)Wenn wir ausstehende Objekte haben, können wir diesen Zustand erkennen, indem wir eine Sammlung in der Session namens Session.new betrachten.
>>> session.new
IdentitySet([User(id=None, name='squidward', fullname='Squidward Tentacles'), User(id=None, name='ehkrabs', fullname='Eugene H. Krabs')])Die obige Ansicht verwendet eine Sammlung namens IdentitySet, die im Wesentlichen eine Python-Menge ist, die in allen Fällen auf der Objektidentität (d. h. mithilfe der integrierten id()-Funktion von Python und nicht auf der Python-Funktion hash()) hasht.
Flushen¶
Die Session verwendet ein Muster namens Unit of Work. Dies bedeutet im Allgemeinen, dass sie Änderungen einzeln sammelt, sie aber erst an die Datenbank kommuniziert, wenn sie benötigt werden. Dies ermöglicht es ihr, bessere Entscheidungen darüber zu treffen, wie DML-SQL basierend auf einer gegebenen Menge ausstehender Änderungen in der Transaktion emittiert werden soll. Wenn sie SQL an die Datenbank emittiert, um die aktuellen Änderungen zu pushen, wird dieser Vorgang als Flush bezeichnet.
Wir können den Flush-Vorgang manuell durch Aufruf der Methode Session.flush() veranschaulichen.
>>> session.flush()
BEGIN (implicit)
INSERT INTO user_account (name, fullname) VALUES (?, ?) RETURNING id
[... (insertmanyvalues) 1/2 (ordered; batch not supported)] ('squidward', 'Squidward Tentacles')
INSERT INTO user_account (name, fullname) VALUES (?, ?) RETURNING id
[insertmanyvalues 2/2 (ordered; batch not supported)] ('ehkrabs', 'Eugene H. Krabs')
Oben beobachten wir, dass die Session zuerst aufgefordert wurde, SQL zu emittieren, also erstellte sie eine neue Transaktion und emittierte die entsprechenden INSERT-Anweisungen für die beiden Objekte. Die Transaktion bleibt nun offen, bis wir eine der Methoden Session.commit(), Session.rollback() oder Session.close() der Session aufrufen.
Obwohl Session.flush() verwendet werden kann, um ausstehende Änderungen manuell in die aktuelle Transaktion zu pushen, ist dies normalerweise nicht erforderlich, da die Session ein Verhalten aufweist, das als Autoflush bezeichnet wird, das wir später veranschaulichen werden. Sie führt auch Änderungen durch, wenn Session.commit() aufgerufen wird.
Automatisch generierte Primärschlüsselattribute¶
Sobald die Zeilen eingefügt sind, befinden sich die beiden von uns erstellten Python-Objekte in einem Zustand namens persistent, in dem sie mit dem Session-Objekt verbunden sind, in dem sie hinzugefügt oder geladen wurden, und viele weitere Verhaltensweisen aufweisen, die später behandelt werden.
Eine weitere Auswirkung des aufgetretenen INSERTs war, dass das ORM die neuen Primärschlüsselidentifikatoren für jedes neue Objekt abgerufen hat; intern verwendet es normalerweise denselben CursorResult.inserted_primary_key-Accessor, den wir zuvor vorgestellt haben. Die Objekte squidward und krabs haben nun diese neuen Primärschlüsselidentifikatoren zugeordnet, und wir können sie durch Zugriff auf das Attribut id sehen.
>>> squidward.id
4
>>> krabs.id
5Tipp
Warum hat das ORM zwei separate INSERT-Anweisungen emittiert, wo es executemany hätte verwenden können? Wie wir im nächsten Abschnitt sehen werden, muss die Session beim Flushen von Objekten immer den Primärschlüssel neu eingefügter Objekte kennen. Wenn eine Funktion wie SQLite's Autoincrement verwendet wird (andere Beispiele sind PostgreSQL IDENTITY oder SERIAL, Verwendung von Sequenzen usw.), erfordert die Funktion CursorResult.inserted_primary_key normalerweise, dass jeder INSERT einzeln emittiert wird. Hätten wir Werte für die Primärschlüssel vorab bereitgestellt, hätte das ORM den Vorgang besser optimieren können. Einige Datenbank-Backends wie psycopg2 können auch viele Zeilen gleichzeitig einfügen und trotzdem Primärschlüsselwerte abrufen.
Objekte anhand des Primärschlüssels aus der Identitätsmap abrufen¶
Die Primärschlüsselidentität der Objekte ist für die Session von Bedeutung, da die Objekte nun mithilfe einer Funktion namens Identitätsmap mit dieser Identität im Speicher verknüpft sind. Die Identitätsmap ist ein In-Memory-Speicher, der alle aktuell im Speicher geladenen Objekte mit ihrer Primärschlüsselidentität verknüpft. Wir können dies beobachten, indem wir eines der obigen Objekte mithilfe der Methode Session.get() abrufen, die einen Eintrag aus der Identitätsmap zurückgibt, wenn dieser lokal vorhanden ist, andernfalls wird ein SELECT emittiert.
>>> some_squidward = session.get(User, 4)
>>> some_squidward
User(id=4, name='squidward', fullname='Squidward Tentacles')Wichtig ist zu beachten, dass die Identitätsmap eine eindeutige Instanz eines bestimmten Python-Objekts pro bestimmter Datenbankidentität im Geltungsbereich eines bestimmten Session-Objekts verwaltet. Wir können beobachten, dass some_squidward auf dasselbe Objekt verweist wie squidward zuvor.
>>> some_squidward is squidward
TrueDie Identitätsmap ist eine kritische Funktion, die es ermöglicht, komplexe Objektsätze innerhalb einer Transaktion zu manipulieren, ohne dass es zu Inkonsistenzen kommt.
Commit¶
Es gibt noch viel mehr über die Funktionsweise der Session zu sagen, was weiter besprochen wird. Vorerst committen wir die Transaktion, damit wir Wissen über das Abrufen von Zeilen sammeln können, bevor wir weitere ORM-Verhaltensweisen und -Funktionen untersuchen.
>>> session.commit()
COMMITDer obige Vorgang committet die laufende Transaktion. Die Objekte, mit denen wir gearbeitet haben, sind weiterhin attached an die Session, ein Zustand, in dem sie verbleiben, bis die Session geschlossen wird (was unter Schließen einer Session eingeführt wird).
Tipp
Wichtig ist, dass Attribute der Objekte, mit denen wir gerade gearbeitet haben, abgelaufen sind. Das bedeutet, wenn wir als Nächstes auf ihre Attribute zugreifen, startet die Session eine neue Transaktion und lädt ihren Zustand neu. Diese Option ist manchmal problematisch, sowohl aus Leistungsgründen als auch wenn man die Objekte nach dem Schließen der Session verwenden möchte (was als detached-Zustand bekannt ist), da sie keinen Zustand haben und keine Session zum Laden dieses Zustands haben, was zu "detached instance"-Fehlern führt. Das Verhalten ist über einen Parameter namens Session.expire_on_commit steuerbar. Mehr dazu unter Schließen einer Session.
ORM-Objekte mithilfe des Unit of Work-Musters aktualisieren¶
Im vorherigen Abschnitt UPDATE- und DELETE-Anweisungen verwenden haben wir das Update-Konstrukt eingeführt, das eine SQL UPDATE-Anweisung repräsentiert. Bei Verwendung des ORM wird dieses Konstrukt auf zwei Arten verwendet. Die primäre Methode ist, dass es automatisch als Teil des Unit of Work-Prozesses der Session emittiert wird, wobei eine UPDATE-Anweisung pro Primärschlüssel für einzelne Objekte mit Änderungen emittiert wird.
Angenommen, wir haben das User-Objekt für den Benutzernamen sandy in eine Transaktion geladen (auch hier werden die Methoden Select.filter_by() und Result.scalar_one() gezeigt)
>>> sandy = session.execute(select(User).filter_by(name="sandy")).scalar_one()
BEGIN (implicit)
SELECT user_account.id, user_account.name, user_account.fullname
FROM user_account
WHERE user_account.name = ?
[...] ('sandy',)
Das Python-Objekt sandy fungiert, wie bereits erwähnt, als Proxy für die Zeile in der Datenbank, genauer gesagt für die Datenbankzeile im Kontext der aktuellen Transaktion, die die Primärschlüsselidentität 2 hat.
>>> sandy
User(id=2, name='sandy', fullname='Sandy Cheeks')Wenn wir die Attribute dieses Objekts ändern, verfolgt die Session diese Änderung.
>>> sandy.fullname = "Sandy Squirrel"Das Objekt erscheint in einer Sammlung namens Session.dirty, was darauf hindeutet, dass das Objekt "dirty" ist.
>>> sandy in session.dirty
TrueWenn die Session als nächstes einen Flush durchführt, wird ein UPDATE emittiert, das diesen Wert in der Datenbank aktualisiert. Wie bereits erwähnt, erfolgt ein Flush automatisch, bevor wir ein SELECT emittieren, mittels eines Verhaltens namens Autoflush. Wir können direkt die Spalte User.fullname aus dieser Zeile abfragen und erhalten unseren aktualisierten Wert zurück.
>>> sandy_fullname = session.execute(select(User.fullname).where(User.id == 2)).scalar_one()
UPDATE user_account SET fullname=? WHERE user_account.id = ?
[...] ('Sandy Squirrel', 2)
SELECT user_account.fullname
FROM user_account
WHERE user_account.id = ?
[...] (2,)
>>> print(sandy_fullname)
Sandy SquirrelWie wir oben sehen können, haben wir die Session angewiesen, eine einzelne select()-Anweisung auszuführen. Die emittierte SQL zeigt jedoch auch, dass ein UPDATE emittiert wurde, was dem Flush-Vorgang zum Pushen ausstehender Änderungen entsprach. Das Python-Objekt sandy wird nun nicht mehr als dirty betrachtet.
>>> sandy in session.dirty
FalseBeachten Sie jedoch, dass wir uns immer noch in einer Transaktion befinden und unsere Änderungen noch nicht in den permanenten Speicher der Datenbank geschrieben wurden. Da Sandys Nachname tatsächlich "Cheeks" und nicht "Squirrel" ist, werden wir diesen Fehler später reparieren, wenn wir die Transaktion zurückrollen. Aber zuerst werden wir einige weitere Datenänderungen vornehmen.
Siehe auch
Flushing - beschreibt den Flush-Vorgang sowie Informationen über die Einstellung Session.autoflush.
ORM-Objekte mithilfe des Unit of Work-Musters löschen¶
Um die grundlegenden Persistenzoperationen abzurunden, kann ein einzelnes ORM-Objekt innerhalb des Unit of Work-Prozesses durch Verwendung der Methode Session.delete() zum Löschen markiert werden. Laden wir patrick aus der Datenbank.
>>> patrick = session.get(User, 3)
SELECT user_account.id AS user_account_id, user_account.name AS user_account_name,
user_account.fullname AS user_account_fullname
FROM user_account
WHERE user_account.id = ?
[...] (3,)
Wenn wir patrick zum Löschen markieren, passiert wie bei anderen Operationen noch nichts, bis ein Flush durchgeführt wird.
>>> session.delete(patrick)Das aktuelle ORM-Verhalten ist, dass patrick in der Session bleibt, bis der Flush durchgeführt wird, was, wie bereits erwähnt, geschieht, wenn wir eine Abfrage ausführen.
>>> session.execute(select(User).where(User.name == "patrick")).first()
SELECT address.id AS address_id, address.email_address AS address_email_address,
address.user_id AS address_user_id
FROM address
WHERE ? = address.user_id
[...] (3,)
DELETE FROM user_account WHERE user_account.id = ?
[...] (3,)
SELECT user_account.id, user_account.name, user_account.fullname
FROM user_account
WHERE user_account.name = ?
[...] ('patrick',)
Oben wurde die von uns angeforderte SELECT-Anweisung von einem DELETE vorangestellt, das die ausstehende Löschung für patrick anzeigte. Es gab auch eine SELECT-Abfrage gegen die address-Tabelle, die durch die Suche des ORM nach Zeilen in dieser Tabelle, die mit der Zielzeile in Beziehung stehen könnten, ausgelöst wurde; dieses Verhalten ist Teil eines Verhaltens namens Kaskade und kann durch die automatische Handhabung verwandter Zeilen in address durch die Datenbank effizienter gestaltet werden; der Abschnitt delete enthält alle Details dazu.
Siehe auch
delete - beschreibt, wie das Verhalten von Session.delete() in Bezug auf die Behandlung verwandter Zeilen in anderen Tabellen optimiert wird.
Darüber hinaus wird die gelöschte Objektinstanz patrick nicht mehr als persistent innerhalb der Session betrachtet, was durch die Containment-Prüfung gezeigt wird.
>>> patrick in session
FalseWie bei den UPDATEs, die wir am Objekt sandy vorgenommen haben, sind jedoch alle hier vorgenommenen Änderungen lokal zu einer laufenden Transaktion, die nicht permanent wird, wenn wir sie nicht committen. Da das Zurückrollen der Transaktion derzeit interessanter ist, werden wir dies im nächsten Abschnitt tun.
Massen-/Mehrzeilen-INSERT, Upsert, UPDATE und DELETE¶
Die in diesem Abschnitt besprochenen Techniken des Unit of Work zielen darauf ab, DML- oder INSERT/UPDATE/DELETE-Anweisungen mit Python-Objektmechanismen zu integrieren, die oft komplexe Graphen von miteinander verbundenen Objekten beinhalten. Sobald Objekte mithilfe von Session.add() zu einer Session hinzugefügt wurden, emittiert der Unit of Work-Prozess automatisch INSERT/UPDATE/DELETE in unserem Namen, wenn Attribute auf unseren Objekten erstellt und modifiziert werden.
Die ORM- Session kann jedoch auch Befehle verarbeiten, die es ihr ermöglichen, INSERT-, UPDATE- und DELETE-Anweisungen direkt zu emittieren, ohne dass ihr ORM-persistierte Objekte übergeben werden. Stattdessen werden Listen von einzufügenden, zu aktualisierenden oder zu upsertenden Werten oder WHERE-Kriterien übergeben, sodass eine UPDATE- oder DELETE-Anweisung, die viele Zeilen gleichzeitig abgleicht, aufgerufen werden kann. Diese Nutzungsweise ist von besonderer Bedeutung, wenn eine große Anzahl von Zeilen betroffen sein muss, ohne dass die Erstellung und Manipulation von zugeordneten Objekten erforderlich ist, was für einfache, leistungsintensive Aufgaben wie große Masseneinfügungen umständlich und unnötig sein kann.
Die Massen- / Mehrzeilenfunktionen des ORM Session nutzen die Konstrukte insert(), update() und delete() direkt, und ihre Verwendung ähnelt der, wie sie mit SQLAlchemy Core verwendet werden (erstmals in diesem Tutorial unter Verwendung von INSERT-Anweisungen und Verwendung von UPDATE- und DELETE-Anweisungen eingeführt). Bei der Verwendung dieser Konstrukte mit der ORM Session anstelle einer reinen Connection sind deren Konstruktion, Ausführung und Ergebnisverarbeitung vollständig in das ORM integriert.
Hintergründe und Beispiele zur Verwendung dieser Funktionen finden Sie im Abschnitt ORM-aktivierte INSERT-, UPDATE- und DELETE-Anweisungen im ORM-Abfragehandbuch.
Rollback¶
Die Session verfügt über eine Methode Session.rollback(), die wie erwartet ein ROLLBACK auf der laufenden SQL-Verbindung auslöst. Sie hat jedoch auch Auswirkungen auf die Objekte, die derzeit mit der Session verbunden sind, in unserem vorherigen Beispiel das Python-Objekt sandy. Während wir den .fullname des sandy-Objekts zu "Sandy Squirrel" geändert haben, möchten wir diese Änderung rückgängig machen. Der Aufruf von Session.rollback() macht nicht nur die Transaktion rückgängig, sondern **macht auch alle Objekte ungültig**, die derzeit mit dieser Session verbunden sind. Dies hat zur Folge, dass sie sich beim nächsten Zugriff über einen Prozess namens Lazy Loading selbst aktualisieren.
>>> session.rollback()
ROLLBACKUm den "Ungültigkeits"-Prozess genauer zu betrachten, können wir feststellen, dass das Python-Objekt sandy bis auf ein spezielles SQLAlchemy-internes Zustandsobjekt keine Zustandsinformationen mehr in seinem Python __dict__ enthält.
>>> sandy.__dict__
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x...>}Dies ist der "ungültige" Zustand; der erneute Zugriff auf das Attribut startet automatisch eine neue Transaktion und aktualisiert sandy mit der aktuellen Datenbankzeile.
>>> sandy.fullname
BEGIN (implicit)
SELECT user_account.id AS user_account_id, user_account.name AS user_account_name,
user_account.fullname AS user_account_fullname
FROM user_account
WHERE user_account.id = ?
[...] (2,)
'Sandy Cheeks'Wir können nun feststellen, dass die vollständige Datenbankzeile auch in das __dict__ des sandy-Objekts geladen wurde.
>>> sandy.__dict__
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x...>,
'id': 2, 'name': 'sandy', 'fullname': 'Sandy Cheeks'}Bei gelöschten Objekten wird, wie wir zuvor bemerkt haben, dass patrick nicht mehr in der Sitzung war, auch die Identität dieses Objekts wiederhergestellt.
>>> patrick in session
Trueund natürlich sind auch die Datenbankdaten wieder vorhanden.
>>> session.execute(select(User).where(User.name == "patrick")).scalar_one() is patrick
SELECT user_account.id, user_account.name, user_account.fullname
FROM user_account
WHERE user_account.name = ?
[...] ('patrick',)
TrueSchließen einer Sitzung¶
In den obigen Abschnitten haben wir ein Session-Objekt außerhalb eines Python-Kontextmanagers verwendet, d. h. wir haben die with-Anweisung nicht verwendet. Das ist in Ordnung, aber wenn wir die Dinge auf diese Weise tun, ist es am besten, die Session ausdrücklich zu schließen, wenn wir damit fertig sind.
>>> session.close()
ROLLBACK
Das Schließen der Session, was auch geschieht, wenn wir sie in einem Kontextmanager verwenden, bewirkt Folgendes:
Es **gibt alle Verbindungsressourcen an den Connection-Pool zurück** und bricht alle laufenden Transaktionen ab (z. B. durch Rollback).
Das bedeutet, dass wir, wenn wir eine Sitzung für rein Leseaufgaben verwenden und sie dann schließen, nicht explizit
Session.rollback()aufrufen müssen, um sicherzustellen, dass die Transaktion zurückgerollt wird; der Connection-Pool kümmert sich darum.Es **entfernt alle Objekte** aus der
Session.Das bedeutet, dass alle Python-Objekte, die wir für diese
Sessiongeladen hatten, wiesandy,patrickundsquidward, sich nun in einem Zustand befinden, der als detached bekannt ist. Insbesondere werden wir feststellen, dass Objekte, die sich noch in einem **ungültigen** Zustand befanden (z. B. aufgrund des Aufrufs vonSession.commit()), nun funktionsunfähig sind, da sie nicht mehr den Zustand einer aktuellen Zeile enthalten und keiner Datenbanktransaktion mehr zugeordnet sind, in der sie aktualisiert werden könnten.# note that 'squidward.name' was just expired previously, so its value is unloaded >>> squidward.name Traceback (most recent call last): ... sqlalchemy.orm.exc.DetachedInstanceError: Instance <User at 0x...> is not bound to a Session; attribute refresh operation cannot proceed
Die detached Objekte können mit der Methode
Session.add()wieder mit derselben oder einer neuenSessionverknüpft werden, was ihre Beziehung zu ihrer jeweiligen Datenbankzeile wiederherstellt.>>> session.add(squidward) >>> squidward.name
BEGIN (implicit) SELECT user_account.id AS user_account_id, user_account.name AS user_account_name, user_account.fullname AS user_account_fullname FROM user_account WHERE user_account.id = ? [...] (4,)'squidward'Tipp
Versuchen Sie, die Verwendung von Objekten im detached-Zustand so weit wie möglich zu vermeiden. Wenn die
Sessiongeschlossen wird, räumen Sie auch Verweise auf alle zuvor angehängten Objekte auf. Für Fälle, in denen detached-Objekte notwendig sind, typischerweise die sofortige Anzeige gerade committeter Objekte für eine Webanwendung, bei der dieSessionvor dem Rendern der Ansicht geschlossen wird, setzen Sie das FlagSession.expire_on_commitaufFalse.
Die Designs von flambé! dem Drachen und Der Alchemist wurden von Rotem Yaari erstellt und großzügig gespendet.
Erstellt mit Sphinx 7.2.6. Dokumentation zuletzt generiert: Di 11 Mär 2025 14:40:17 EDT