Soweit ich weiß, gibt es keine Möglichkeit, das ORM dazu zu bringen, Masseneinsätze auszustellen. Ich glaube, der Grund dafür ist, dass SQLAlchemy die Identität jedes Objekts (dh neue Primärschlüssel) verfolgen muss, und Bulk-Einfügungen stören dies. Angenommen, Ihre foo
Tabelle enthält eine id
Spalte und ist einer Foo
Klasse zugeordnet:
x = Foo(bar=1)
print x.id
# None
session.add(x)
session.flush()
# BEGIN
# INSERT INTO foo (bar) VALUES(1)
# COMMIT
print x.id
# 1
Da SQLAlchemy den Wert für x.id
ohne weitere Abfrage ermittelt hat, können wir daraus schließen, dass der Wert direkt aus der INSERT
Anweisung stammt. Wenn Sie keinen späteren Zugriff auf die erstellten Objekte über dieselben Instanzen benötigen , können Sie die ORM-Ebene für Ihre Einfügung überspringen:
Foo.__table__.insert().execute([{'bar': 1}, {'bar': 2}, {'bar': 3}])
# INSERT INTO foo (bar) VALUES ((1,), (2,), (3,))
SQLAlchemy kann diese neuen Zeilen nicht mit vorhandenen Objekten abgleichen, daher müssen Sie sie für nachfolgende Vorgänge erneut abfragen.
In Bezug auf veraltete Daten ist es hilfreich, sich daran zu erinnern, dass die Sitzung keine integrierte Methode enthält, um festzustellen, wann die Datenbank außerhalb der Sitzung geändert wird. Um über vorhandene Instanzen auf extern geänderte Daten zugreifen zu können, müssen die Instanzen als abgelaufen markiert werden . Dies geschieht standardmäßig am session.commit()
, kann jedoch manuell durch Aufrufen von session.expire_all()
oder erfolgen session.expire(instance)
. Ein Beispiel (SQL weggelassen):
x = Foo(bar=1)
session.add(x)
session.commit()
print x.bar
# 1
foo.update().execute(bar=42)
print x.bar
# 1
session.expire(x)
print x.bar
# 42
session.commit()
läuft ab x
, sodass die erste print-Anweisung implizit eine neue Transaktion öffnet und erneut abfragtx
die Attribute erneut ab. Wenn Sie die erste Druckanweisung auskommentieren, werden Sie feststellen, dass die zweite jetzt den richtigen Wert aufnimmt, da die neue Abfrage erst nach der Aktualisierung ausgegeben wird.
Dies ist unter dem Gesichtspunkt der Transaktionsisolation sinnvoll - Sie sollten nur externe Änderungen zwischen Transaktionen vornehmen. Wenn dies zu Problemen führt, würde ich vorschlagen, die Transaktionsgrenzen Ihrer Anwendung zu klären oder zu überdenken, anstatt sofort danach zu greifen session.expire_all()
.