SQLAlchemy 2.0 Dokumentation
Änderungen und Migration
- SQLAlchemy 2.0 - Major Migration Guide
- Was ist neu in SQLAlchemy 2.0?
- 2.0 Changelog
- 1.4 Changelog
- 1.3 Changelog
- 1.2 Changelog
- 1.1 Changelog
- 1.0 Changelog
- 0.9 Changelog
- 0.8 Changelog
- 0.7 Changelog
- 0.6 Changelog
- 0.5 Changelog
- 0.4 Changelog
- 0.3 Changelog
- 0.2 Changelog
- 0.1 Changelog
- Was ist neu in SQLAlchemy 1.4?
- Was ist neu in SQLAlchemy 1.3?
- Was ist neu in SQLAlchemy 1.2?
- Was ist neu in SQLAlchemy 1.1?
- Was ist neu in SQLAlchemy 1.0?
- Was ist neu in SQLAlchemy 0.9?
- Was ist neu in SQLAlchemy 0.8?
- Was ist neu in SQLAlchemy 0.7?
- Was ist neu in SQLAlchemy 0.6?
- Was gibt es Neues in SQLAlchemy 0.5?¶
- Was ist neu in SQLAlchemy 0.4?
Projektversionen
- Vorher: Was gibt es Neues in SQLAlchemy 0.6?
- Nächste: Was gibt es Neues in SQLAlchemy 0.4?
- Nach oben: Startseite
- Auf dieser Seite
Was gibt es Neues in SQLAlchemy 0.5?¶
Über dieses Dokument
Dieses Dokument beschreibt die Änderungen zwischen SQLAlchemy Version 0.4, zuletzt veröffentlicht am 12. Oktober 2008, und SQLAlchemy Version 0.5, zuletzt veröffentlicht am 16. Januar 2010.
Dokumentdatum: 4. August 2009
Diese Anleitung dokumentiert API-Änderungen, die Benutzer betrifft, die ihre Anwendungen von der SQLAlchemy 0.4-Reihe auf 0.5 migrieren. Sie wird auch für diejenigen empfohlen, die mit Essential SQLAlchemy arbeiten, das nur 0.4 abdeckt und sogar einige alte 0.3-Eigenheiten enthält. Beachten Sie, dass SQLAlchemy 0.5 viele Verhaltensweisen entfernt, die während der 0.4-Reihe veraltet waren, und auch weitere, spezifische Verhaltensweisen für 0.4 veraltet.
Wichtige Dokumentationsänderungen¶
Einige Abschnitte der Dokumentation wurden komplett neu geschrieben und können als Einführung in neue ORM-Funktionen dienen. Insbesondere die Objekte Query und Session weisen deutliche Unterschiede in API und Verhalten auf, die viele der grundlegenden Arbeitsweisen grundlegend verändern, insbesondere im Hinblick auf die Erstellung hochgradig angepasster ORM-Abfragen und den Umgang mit veralteten Sitzungszuständen, Commits und Rollbacks.
Deprecations Quelle¶
Eine weitere Informationsquelle ist in einer Reihe von Unit-Tests dokumentiert, die den aktuellen Stand der Nutzung einiger gängiger Query-Muster veranschaulichen; diese Datei kann unter [source:sqlalchemy/trunk/test/orm/test_deprecations.py] eingesehen werden.
Änderungen bei den Anforderungen¶
Python 2.4 oder höher ist erforderlich. Die SQLAlchemy 0.4-Linie ist die letzte Version mit Python 2.3-Unterstützung.
Objektrelationale Abbildung¶
Spaltenbasierte Ausdrücke innerhalb von Query. - Wie im Tutorial detailliert, hat
Querydie Fähigkeit, spezifische SELECT-Anweisungen zu erstellen, nicht nur für vollständige Zeilen.session.query(User.name, func.count(Address.id).label("numaddresses")).join( Address ).group_by(User.name)
Die Tupel, die von Mehrspalten-/Entitätsabfragen zurückgegeben werden, sind benannte Tupel.
for row in ( session.query(User.name, func.count(Address.id).label("numaddresses")) .join(Address) .group_by(User.name) ): print("name", row.name, "number", row.numaddresses)
Queryverfügt über einenstatement-Accessor sowie einesubquery()-Methode, die es ermöglichen,Queryzur Erstellung komplexerer Kombinationen zu verwenden.subq = ( session.query(Keyword.id.label("keyword_id")) .filter(Keyword.name.in_(["beans", "carrots"])) .subquery() ) recipes = session.query(Recipe).filter( exists() .where(Recipe.id == recipe_keywords.c.recipe_id) .where(recipe_keywords.c.keyword_id == subq.c.keyword_id) )
Explizite ORM-Aliase werden für Aliase-Joins empfohlen - Die Funktion
aliased()erzeugt einen „Alias“ einer Klasse, der eine feingranulare Kontrolle über Aliase in Verbindung mit ORM-Abfragen ermöglicht. Während ein Tabellen-Alias (d. h.table.alias()) immer noch verwendbar ist, behält ein ORM-Alias die Semantik des ORM-gemappten Objekts bei, was für Vererbungszuordnungen, Optionen und andere Szenarien bedeutsam ist. Z.B.Friend = aliased(Person) session.query(Person, Friend).join((Friend, Person.friends)).all()
query.join() stark verbessert. - Sie können jetzt das Ziel und die ON-Klausel für einen Join auf verschiedene Arten angeben. Eine Zielklasse allein kann angegeben werden, wobei SQLA versucht, einen Join zu ihr über einen Fremdschlüssel herzustellen, ähnlich wie bei
table.join(someothertable). Ein Ziel und eine explizite ON-Bedingung können angegeben werden, wobei die ON-Bedingung einrelation()-Name, ein tatsächlicher Klassen-Deskriptor oder ein SQL-Ausdruck sein kann. Oder die alte Methode, nur einenrelation()-Namen oder Klassen-Deskriptor anzugeben, funktioniert auch. Siehe das ORM-Tutorial, das mehrere Beispiele enthält.Deklarative wird für Anwendungen empfohlen, die keine Abstraktion zwischen Tabellen und Mappern erfordern (und nicht bevorzugen) - Das [/docs/05/reference/ext/declarative.html Deklarative]-Modul, das zur Kombination des Ausdrucks von
Table,mapper()und benutzerdefinierten Klassenobjekten verwendet wird, wird dringend empfohlen, da es die Anwendungskonfiguration vereinfacht, das „ein Mapper pro Klasse“-Muster sicherstellt und den vollen Konfigurationsumfang ermöglicht, der für separatemapper()-Aufrufe verfügbar ist. Die separate Verwendung vonmapper()undTablewird nun als „klassische SQLAlchemy-Nutzung“ bezeichnet und ist natürlich frei mit Deklarative mischebar.Das .c.-Attribut wurde aus Klassen entfernt (d. h.
MyClass.c.somecolumn). Wie in 0.4 sind klassenbasierte Eigenschaften als Abfrageelemente nutzbar, d. h.Class.c.propnamewird nun vonClass.propnameabgelöst, und dasc-Attribut verbleibt weiterhin aufTable-Objekten, wo es den Namensraum der auf der Tabelle vorhandenenColumn-Objekte angibt.Um auf die Tabelle für eine gemappte Klasse zuzugreifen (falls Sie diese nicht bereits aufbewahrt haben)
table = class_mapper(someclass).mapped_table
Spalten durchlaufen
for col in table.c: print(col)
Mit einer bestimmten Spalte arbeiten
table.c.somecolumn
Die klassengebundenen Deskriptoren unterstützen die vollständige Menge an Spaltenoperatoren sowie die dokumentierten beziehungsbezogenen Operatoren wie
has(),any(),contains()usw.Der Grund für die harte Entfernung von
.c.ist, dass in 0.5 klassengebundene Deskriptoren potenziell unterschiedliche Bedeutungen und Informationen bezüglich Klassenabbildungen im Vergleich zu einfachenColumn-Objekten tragen – und es gibt Anwendungsfälle, bei denen man spezifisch das eine oder das andere verwenden möchte. Im Allgemeinen ruft die Verwendung klassengebundener Deskriptoren eine Reihe von Mapping-/polymorphiebewussten Übersetzungen auf, und die Verwendung tabellenbasierter Spalten nicht. In 0.4 wurden diese Übersetzungen pauschal auf alle Ausdrücke angewendet, 0.5 unterscheidet jedoch vollständig zwischen Spalten und gemappten Deskriptoren und wendet Übersetzungen nur auf letztere an. In vielen Fällen, insbesondere bei Joined-Table-Inheritance-Konfigurationen sowie bei der Verwendung vonquery(<columns>), sindClass.propnameundtable.c.colnamenicht austauschbar.Zum Beispiel unterscheidet sich
session.query(users.c.id, users.c.name)vonsession.query(User.id, User.name); im letzteren Fall ist dieQuerysich des verwendeten Mappers bewusst und weitere mappertypspezifische Operationen wiequery.join(<propname>),query.with_parent()usw. können verwendet werden, im ersteren Fall jedoch nicht. Darüber hinaus beziehen sich in polymorphen Vererbungsszenarien die klassengebundenen Deskriptoren auf die Spalten im verwendeten polymorphen wählbaren Objekt und nicht notwendigerweise auf die Tabellenspalte, die direkt dem Deskriptor entspricht. Zum Beispiel werden eine Reihe von Klassen, die durch Joined-Table-Inheritance mit derperson-Tabelle über dieperson_id-Spalte jeder Tabelle verbunden sind, alle ihrClass.person_id-Attribut auf dieperson_id-Spalte inpersonund nicht auf ihre Unterklassentabelle gemappt haben. Version 0.4 würde dieses Verhalten automatisch auf tabellenbasierteColumn-Objekte anwenden. In 0.5 wurde diese automatische Konvertierung entfernt, sodass Sie tatsächlich tabellenbasierte Spalten als Mittel zur Überschreibung der Übersetzungen verwenden *können*, die bei polymorphen Abfragen auftreten; dies ermöglichtQuery, optimierte Selects für Joined-Table- oder Concrete-Table-Inheritance-Setups sowie portierbare Subqueries usw. zu erstellen.Sitzung synchronisiert sich jetzt automatisch mit Transaktionen. Die Sitzung synchronisiert sich jetzt standardmäßig automatisch mit der Transaktion, einschließlich Autoflush und Autoexpire. Eine Transaktion ist jederzeit vorhanden, es sei denn, sie wird über die Option
autocommitdeaktiviert. Wenn alle drei Flags auf ihre Standardwerte gesetzt sind, erholt sich die Sitzung nach Rollbacks gut und es ist sehr schwierig, veraltete Daten in die Sitzung zu bekommen. Siehe die neue Sitzungsdokumentation für Details.Implizites Order By wurde entfernt. Dies wirkt sich auf ORM-Benutzer aus, die sich auf das „implizite Ordering“-Verhalten von SA verlassen, das besagt, dass alle Query-Objekte, die keine
order_by()haben, nach der „id“- oder „oid“-Spalte der primär gemappten Tabelle sortiert werden und alle lazy/eagerly geladenen Sammlungen eine ähnliche Sortierung anwenden. In 0.5 muss die automatische Sortierung explizit aufmapper()undrelation()-Objekten (falls gewünscht) oder ansonsten bei Verwendung vonQuerykonfiguriert werden.Um ein 0.4-Mapping auf 0.5 zu konvertieren, damit sein Sortierverhalten dem von 0.4 oder früher extrem ähnlich ist, verwenden Sie die Einstellung
order_byaufmapper()undrelation()mapper( User, users, properties={"addresses": relation(Address, order_by=addresses.c.id)}, order_by=users.c.id, )
Um die Sortierung für einen Backref festzulegen, verwenden Sie die Funktion
backref()"keywords": relation( Keyword, secondary=item_keywords, order_by=keywords.c.name, backref=backref("items", order_by=items.c.id), )
Deklarativ verwenden? Um die neue
order_by-Anforderung zu unterstützen, könnenorder_byund ähnliche nun mit Zeichenfolgen gesetzt werden, die später in Python ausgewertet werden (dies funktioniert **nur** mit Deklarative, nicht mit reinen Mappern)class MyClass(MyDeclarativeBase): ... "addresses": relation("Address", order_by="Address.id")
Es ist im Allgemeinen eine gute Idee,
order_byaufrelation()szu setzen, die Listen-basierte Sammlungen von Elementen laden, da diese Sortierung sonst nicht beeinflusst werden kann. Abgesehen davon ist die beste Praxis,Query.order_by()zu verwenden, um die Sortierung der primär geladenen Entitäten zu steuern.Session ist jetzt autoflush=True/autoexpire=True/autocommit=False. - Um sie einzurichten, rufen Sie einfach
sessionmaker()ohne Argumente auf. Der Nametransactional=Trueist jetztautocommit=False. Flushes erfolgen bei jeder Abfrage (deaktivierbar mitautoflush=False), bei jedemcommit()(wie immer) und vor jedembegin_nested()(damit das Zurückrollen zum SAVEPOINT sinnvoll ist). Alle Objekte werden nach jedemcommit()und nach jedemrollback()abgelaufen. Nach dem Rollback werden ausstehende Objekte gelöscht, gelöschte Objekte werden wieder in den persistenten Zustand versetzt. Diese Standardeinstellungen funktionieren sehr gut zusammen und es besteht wirklich kein Bedarf mehr an alten Techniken wieclear()(das inexpunge_all()umbenannt wurde).PS: Sitzungen sind nach einem
rollback()wieder wiederverwendbar. Skalare und Sammlungsattributänderungen, Hinzufügungen und Löschungen werden alle zurückgerollt.session.add() ersetzt session.save(), session.update(), session.save_or_update(). - Die Methoden
session.add(someitem)undsession.add_all([list of items])ersetzensave(),update()undsave_or_update(). Diese Methoden bleiben während 0.5 veraltet.Backref-Konfiguration weniger ausführlich. - Die Funktion
backref()verwendet jetzt die Argumenteprimaryjoinundsecondaryjoinder nach vorne gerichtetenrelation(), wenn diese nicht explizit angegeben sind. Es ist nicht mehr notwendig,primaryjoin/secondaryjoinin beide Richtungen separat anzugeben.Vereinfachte polymorphe Optionen. - Das „polymorphic load“-Verhalten des ORM wurde vereinfacht. In 0.4 hatte mapper() ein Argument namens
polymorphic_fetch, das alsselectoderdeferredkonfiguriert werden konnte. Diese Option wurde entfernt; der Mapper wird nun einfach alle Spalten verzögern, die nicht in der SELECT-Anweisung vorhanden waren. Die tatsächliche SELECT-Anweisung wird durch das Mapper-Argumentwith_polymorphic(das auch in 0.4 vorhanden ist undselect_tableersetzt) sowie durch die Methodewith_polymorphic()aufQuery(ebenfalls in 0.4) gesteuert.Eine Verbesserung der verzögerten Ladung von erbenden Klassen besteht darin, dass der Mapper nun in allen Fällen die „optimierte“ Version der SELECT-Anweisung erzeugt; das heißt, wenn Klasse B von A erbt und mehrere Attribute, die nur auf Klasse B vorhanden sind, abgelaufen sind, enthält die Aktualisierungsoperation nur die Tabelle von B in der SELECT-Anweisung und wird nicht zu A verknüpft.
Die Methode
execute()aufSessionkonvertiert einfache Zeichenfolgen intext()-Konstrukte, sodass Bindungsparameter alle als „:bindname“ angegeben werden können, ohnetext()explizit aufrufen zu müssen. Wenn hier „roher“ SQL gewünscht ist, verwenden Siesession.connection().execute("raw text").session.Query().iterate_instances()wurde ininstances()umbenannt. Die alte Methodeinstances(), die eine Liste statt eines Iterators zurückgab, existiert nicht mehr. Wenn Sie sich auf dieses Verhalten verlassen haben, sollten Sielist(your_query.instances())verwenden.
Erweiterung des ORM¶
In 0.5 gehen wir mit mehr Möglichkeiten zur Modifizierung und Erweiterung des ORM voran. Hier ist eine Zusammenfassung
MapperExtension. - Dies ist die klassische Erweiterungsklasse, die erhalten bleibt. Methoden, die selten benötigt werden sollten, sind
create_instance()undpopulate_instance(). Um die Initialisierung eines Objekts zu steuern, wenn es aus der Datenbank geladen wird, verwenden Sie die Methodereconstruct_instance()oder einfacher den Dekorator@reconstructor, der in der Dokumentation beschrieben ist.SessionExtension. - Dies ist eine einfach zu verwendende Erweiterungsklasse für Sitzungsereignisse. Insbesondere bietet sie die Methoden
before_flush(),after_flush()undafter_flush_postexec(). Diese Verwendung wird in vielen Fällen gegenüberMapperExtension.before_XXXempfohlen, da Sie innerhalb vonbefore_flush()den Flush-Plan der Sitzung frei ändern können, was ausMapperExtensionnicht möglich ist.AttributeExtension. - Diese Klasse ist jetzt Teil der öffentlichen API und ermöglicht die Abfangen von Userland-Ereignissen auf Attributen, einschließlich Attributset- und Löschoperationen sowie Sammlungsanhänge und -entfernungen. Sie ermöglicht auch die Modifizierung des gesetzten oder angehängten Wertes. Der Dekorator
@validates, der in der Dokumentation beschrieben ist, bietet eine schnelle Möglichkeit, alle gemappten Attribute als durch eine bestimmte Klassenmethode „validiert“ zu markieren.Anpassung der Attributinstrumentierung. - Eine API wird für ehrgeizige Bemühungen bereitgestellt, die Attributinstrumentierung von SQLAlchemy vollständig zu ersetzen oder sie in einigen Fällen einfach zu ergänzen. Diese API wurde für das Trellis-Toolkit erstellt, ist aber als öffentliche API verfügbar. Einige Beispiele sind in der Distribution im Verzeichnis
/examples/custom_attributesenthalten.
Schema/Typen¶
String ohne Länge generiert nicht mehr TEXT, sondern VARCHAR - Der Typ
Stringwird nicht mehr magisch in einenText-Typ umgewandelt, wenn er ohne Länge angegeben wird. Dies hat nur Auswirkungen, wenn CREATE TABLE ausgegeben wird, da dannVARCHARohne Längenparameter ausgegeben wird, was auf vielen (aber nicht allen) Datenbanken nicht gültig ist. Um eine TEXT-Spalte (oder CLOB, d. h. unbegrenzten String) zu erstellen, verwenden Sie den TypText.PickleType() mit mutable=True erfordert eine __eq__() Methode - Der Typ
PickleTypemuss Werte vergleichen, wenn mutable=True ist. Die Methode zum Vergleichen vonpickle.dumps()ist ineffizient und unzuverlässig. Wenn ein eingehendes Objekt keine__eq__()-Methode implementiert und auch nichtNoneist, wird derdumps()-Vergleich verwendet, aber eine Warnung ausgegeben. Für Typen, die__eq__()implementieren (was für alle Dictionaries, Listen usw. gilt), wird der Vergleich mit==durchgeführt und ist jetzt standardmäßig zuverlässig.convert_bind_param() und convert_result_value() Methoden von TypeEngine/TypeDecorator werden entfernt. - Das O’Reilly-Buch hat diese Methoden leider dokumentiert, obwohl sie nach 0.3 als veraltet markiert waren. Für einen benutzerdefinierten Typ, der von
TypeEngineerbt, sollten die Methodenbind_processor()undresult_processor()für Bindungs-/Ergebnisverarbeitung verwendet werden. Jeder benutzerdefinierte Typ, ob er vonTypeEngineoderTypeDecoratorerbt und den alten 0.3-Stil verwendet, kann mit dem folgenden Adapter einfach an den neuen Stil angepasst werdenclass AdaptOldConvertMethods(object): """A mixin which adapts 0.3-style convert_bind_param and convert_result_value methods """ def bind_processor(self, dialect): def convert(value): return self.convert_bind_param(value, dialect) return convert def result_processor(self, dialect): def convert(value): return self.convert_result_value(value, dialect) return convert def convert_result_value(self, value, dialect): return value def convert_bind_param(self, value, dialect): return value
Um den obigen Mixin zu verwenden
class MyType(AdaptOldConvertMethods, TypeEngine): ...
Das
quote-Flag beiColumnundTablesowie dasquote_schema-Flag beiTablesteuern nun die Anführungszeichen sowohl positiv als auch negativ. Der Standardwert istNone, d. h. es werden die regulären Anführungsregeln angewendet. WennTrue, werden Anführungszeichen erzwungen. WennFalse, werden Anführungszeichen deaktiviert.Der
DEFAULT-Wert DDL für Spalten kann jetzt bequemer mitColumn(..., server_default='val')angegeben werden, wasColumn(..., PassiveDefault('val'))veraltet.default=ist jetzt ausschließlich für Python-initiierte Standardwerte und kann mit server_default koexistieren. Ein neuesserver_default=FetchedValue()ersetzt dasPassiveDefault('')-Idiom, um Spalten als von externen Triggern beeinflusst zu markieren und hat keine DDL-Nebeneffekte.Die
DateTime-,Time- undDate-Typen von SQLite **akzeptieren jetzt nur noch datetime-Objekte, keine Zeichenfolgen** mehr als Eingabe für Bindungsparameter. Wenn Sie Ihren eigenen „hybriden“ Typ erstellen möchten, der Zeichenfolgen akzeptiert und Ergebnisse als Datumsobjekte (aus welchem Format auch immer Sie möchten) zurückgibt, erstellen Sie einenTypeDecorator, der aufStringaufbaut. Wenn Sie nur zeichenfolgenbasierte Daten möchten, verwenden Sie einfachString.Zusätzlich stellen die Typen
DateTimeundTimebei Verwendung mit SQLite nun das „Mikrosekunden“-Feld des Pythondatetime.datetime-Objekts auf die gleiche Weise wiestr(datetime)dar – als Bruchteil von Sekunden, nicht als Anzahl von Mikrosekunden. Das heißt:dt = datetime.datetime(2008, 6, 27, 12, 0, 0, 125) # 125 usec # old way "2008-06-27 12:00:00.125" # new way "2008-06-27 12:00:00.000125"
Wenn also eine bestehende SQLite-Datenbank, die auf Dateien basiert, über 0.4 und 0.5 hinweg verwendet werden soll, müssen Sie entweder die datetime-Spalten aktualisieren, um das neue Format zu speichern (HINWEIS: Bitte testen Sie dies, ich bin ziemlich sicher, dass es korrekt ist)
UPDATE mytable SET somedatecol = substr(somedatecol, 0, 19) || '.' || substr((substr(somedatecol, 21, -1) / 1000000), 3, -1);
oder den „Legacy“-Modus wie folgt aktivieren
from sqlalchemy.databases.sqlite import DateTimeMixin DateTimeMixin.__legacy_microseconds__ = True
Connection Pool nicht mehr standardmäßig threadlocal¶
0.4 hat eine unglückliche Standardeinstellung von „pool_threadlocal=True“, die zu überraschendem Verhalten führt, wenn beispielsweise mehrere Sitzungen innerhalb eines Threads verwendet werden. Dieses Flag ist in 0.5 jetzt deaktiviert. Um das Verhalten von 0.4 wieder zu aktivieren, geben Sie pool_threadlocal=True an create_engine() an oder verwenden Sie alternativ die Strategie „threadlocal“ über strategy="threadlocal".
*args akzeptiert, *args nicht mehr akzeptiert¶
Die Richtlinie für method(\*args) vs. method([args]) lautet: Wenn die Methode eine variable Anzahl von Elementen akzeptiert, die eine feste Struktur darstellen, nimmt sie \*args. Wenn die Methode eine variable Anzahl von Elementen akzeptiert, die datengesteuert sind, nimmt sie [args].
Die verschiedenen Funktionen
eagerload(),eagerload_all(),lazyload(),contains_eager(),defer(),undefer()von Query.options() akzeptieren jetzt variable Länge von\*keysals ihr Argument, was einen Pfad ermöglicht, der über Deskriptoren formuliert wird, z. B.:query.options(eagerload_all(User.orders, Order.items, Item.keywords))
Ein einzelnes Array-Argument wird aus Kompatibilitätsgründen immer noch akzeptiert.
Ähnlich akzeptieren die Methoden
Query.join()undQuery.outerjoin()eine variable Länge von *args, wobei ein einzelnes Array zur Rückwärtskompatibilität akzeptiert wird.query.join("orders", "items") query.join(User.orders, Order.items)
Die Methode
in_()auf Spalten und ähnlichem akzeptiert jetzt nur noch ein Listenargument. Sie akzeptiert keine\*argsmehr.
Entfernt¶
entity_name - Dieses Feature war immer problematisch und selten genutzt. Die detaillierteren Anwendungsfälle von 0.5 offenbarten weitere Probleme mit
entity_name, die zu seiner Entfernung führten. Wenn für eine einzelne Klasse unterschiedliche Mappings erforderlich sind, teilen Sie die Klasse in separate Unterklassen auf und mappen Sie sie separat. Ein Beispiel hierfür finden Sie unter [wiki:UsageRecipes/EntityName]. Weitere Informationen zur Begründung finden Sie unter https://groups.google.c om/group/sqlalchemy/browse_thread/thread/9e23a0641a88b96d?hl=en.get()/load() Bereinigung
Die Methode
load()wurde entfernt. Ihre Funktionalität war eher willkürlich und kopierte im Wesentlichen Hibernate, wo sie ebenfalls keine besonders sinnvolle Methode ist.Um eine äquivalente Funktionalität zu erhalten
x = session.query(SomeClass).populate_existing().get(7)
Session.get(cls, id)undSession.load(cls, id)wurden entfernt.Session.get()ist redundant gegenübersession.query(cls).get(id).MapperExtension.get()ist ebenfalls entfernt (wie auchMapperExtension.load()). Um die Funktionalität vonQuery.get()zu überschreiben, verwenden Sie eine Unterklasseclass MyQuery(Query): def get(self, ident): ... session = sessionmaker(query_cls=MyQuery)() ad1 = session.query(Address).get(1)
sqlalchemy.orm.relation()Die folgenden veralteten Schlüsselwortargumente wurden entfernt
foreignkey, association, private, attributeext, is_backref
Insbesondere wird
attributeextdurchextensionersetzt – die KlasseAttributeExtensionist jetzt Teil der öffentlichen API.session.Query()Die folgenden veralteten Funktionen wurden entfernt
list, scalar, count_by, select_whereclause, get_by, select_by, join_by, selectfirst, selectone, select, execute, select_statement, select_text, join_to, join_via, selectfirst_by, selectone_by, apply_max, apply_min, apply_avg, apply_sum
Zusätzlich wurde das Schlüsselwortargument
idfürjoin(),outerjoin(),add_entity()undadd_column()entfernt. Um Tabellenaliase inQueryauf Ergebnisspalten zu zielen, verwenden Sie denaliased-Konstrukt.from sqlalchemy.orm import aliased address_alias = aliased(Address) print(session.query(User, address_alias).join((address_alias, User.addresses)).all())
sqlalchemy.orm.Mapperinstances()
get_session() - Diese Methode war nicht sehr auffällig, hatte aber den Effekt, dass sie Lazy Loads mit einer bestimmten Sitzung assoziierte, selbst wenn das übergeordnete Objekt vollständig getrennt war, wenn eine Erweiterung wie
scoped_session()oder das alteSessionContextExtverwendet wurde. Es ist möglich, dass einige Anwendungen, die sich auf dieses Verhalten verlassen haben, nicht mehr wie erwartet funktionieren; aber die bessere Programmierpraxis ist hier, immer sicherzustellen, dass Objekte innerhalb von Sitzungen vorhanden sind, wenn Datenbankzugriffe von ihren Attributen benötigt werden.
mapper(MyClass, mytable)Gemappte Klassen werden nicht mehr mit einem „c“-Klassenattribut instrumentiert; z. B.
MyClass.csqlalchemy.orm.collectionsDer Alias _prepare_instrumentation für prepare_instrumentation wurde entfernt.
sqlalchemy.ormEntfernte den Alias
EXT_PASSvonEXT_CONTINUE.sqlalchemy.engineDer Alias von
DefaultDialect.preexecute_sequenceszu.preexecute_pk_sequenceswurde entfernt.Die veraltete Funktion engine_descriptors() wurde entfernt.
sqlalchemy.ext.activemapperModul entfernt.
sqlalchemy.ext.assignmapperModul entfernt.
sqlalchemy.ext.associationproxyDas Durchreichen von Keyword-Args bei
.append(item, \**kw)des Proxys wurde entfernt und ist jetzt einfach.append(item)sqlalchemy.ext.selectresults,sqlalchemy.mods.selectresultsModule entfernt.
sqlalchemy.ext.declarativedeclared_synonym()entfernt.sqlalchemy.ext.sessioncontextModul entfernt.
sqlalchemy.logDer Alias
SADeprecationWarningfürsqlalchemy.exc.SADeprecationWarningwurde entfernt.sqlalchemy.excexc.AssertionErrorwurde entfernt und die Verwendung wurde durch das gleichnamige Python-Built-in ersetzt.sqlalchemy.databases.mysqlDie veraltete Dialektmethode
get_version_infowurde entfernt.
Umbenannt oder verschoben¶
sqlalchemy.exceptionsist jetztsqlalchemy.excDas Modul kann bis Version 0.6 noch unter dem alten Namen importiert werden.
FlushError,ConcurrentModificationError,UnmappedColumnError-> sqlalchemy.orm.excDiese Ausnahmen wurden in das ORM-Paket verschoben. Der Import von ‚sqlalchemy.orm‘ installiert Aliase in sqlalchemy.exc zur Kompatibilität bis Version 0.6.
sqlalchemy.logging->sqlalchemy.logDieses interne Modul wurde umbenannt. Muss nicht mehr speziell behandelt werden, wenn SA mit py2app und ähnlichen Tools, die Imports scannen, verpackt wird.
session.Query().iterate_instances()->session.Query().instances().
Veraltet¶
Session.save(),Session.update(),Session.save_or_update()Alle drei wurden durch
Session.add()ersetztsqlalchemy.PassiveDefaultVerwenden Sie
Column(server_default=...). Übersetzt intern zu sqlalchemy.DefaultClause().session.Query().iterate_instances(). Es wurde ininstances()umbenannt.
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