O ile mi wiadomo, nie ma sposobu, aby ORM wydał inserty luzem. Uważam, że podstawową przyczyną jest to, że SQLAlchemy musi śledzić tożsamość każdego obiektu (tj. Nowe klucze podstawowe), a wkładki zbiorcze kolidują z tym. Na przykład, zakładając swoją tabelę foo
zawiera kolumnę id
i jest odwzorowany na Foo
Klasa:
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
Od SQLAlchemy podniósł wartość dla x.id
bez wydawania kolejne zapytanie, możemy wywnioskować, że to ma wartość bezpośrednio z INSERT
oświadczenie. Jeśli nie potrzebują kolejnego dostęp do tworzonych obiektów poprzez samych przypadkach można pominąć warstwę ORM dla wkładki:
Foo.__table__.insert().execute([{'bar': 1}, {'bar': 2}, {'bar': 3}])
# INSERT INTO foo (bar) VALUES ((1,), (2,), (3,))
SQLAlchemy nie może się równać z tych nowych wierszy z istniejących obiektów, tak będziesz musiał przesłać nowe zapytanie do kolejnych operacji.
Jeśli chodzi o nieaktualne dane, warto pamiętać, że sesja nie ma wbudowanego sposobu sprawdzania, czy baza danych została zmieniona poza sesją. Aby uzyskać dostęp do danych zmodyfikowanych zewnętrznie za pośrednictwem istniejących instancji, wystąpienia muszą być oznaczone jako wygasły. Dzieje się tak domyślnie na session.commit()
, ale można to zrobić ręcznie, dzwoniąc pod numer session.expire_all()
lub session.expire(instance)
. Przykładem (SQL pominięta):
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()
wygasa x
, więc pierwsza instrukcja print domyślnie otwiera nową transakcję i ponownie zapytań x
„s atrybuty. Jeśli skomentujesz pierwszą instrukcję drukowania, zauważysz, że druga z nich odbiera teraz poprawną wartość, ponieważ nowe zapytanie nie zostanie wysłane dopiero po aktualizacji.
Ma to sens z punktu widzenia izolacji transakcyjnej - należy wybierać tylko zewnętrzne modyfikacje między transakcjami. Jeśli powoduje to problemy, sugeruję wyjaśnienie lub ponowne przemyślenie granic transakcji, zamiast natychmiastowego osiągnięcia wartości session.expire_all()
.
To może pomóc: http://stackoverflow.com/questions/270879/efficiently-updating-database-using-sqlalchemy-orm/278606#278606 –
Nick, rozumiem, że jest to * bardzo * old post . Czy byłoby możliwe zaktualizowanie tytułu do czegoś * poprawnego * jak "wielokrotny wkład rekordu z SQLAlchemy ORM". Instrukcje wstawiania wielu rekordów, takie jak te, które podałeś, różnią się znacznie od operacji ładowania zbiorczego na poziomie bazy danych. Wkładki masowe są przeznaczone do 1k + przesyłanie danych, zwykle z dużych zestawów danych i wykonywane przez menedżerów aplikacji, a nie operacje REST lub kod poziomu aplikacji .... Używajmy poprawnie naszej nomenklatury. – W4t3randWind