2013-02-02 6 views
8

Co jest poprawne? Wiem, że pierwsze zadziała, ale podejrzewam, że to więcej pracy dla DB niż jest to konieczne. Czy druga praca będzie równie dobrze, ale z mniejszą ilością pracy dla DB? Używam MySQL FWIW.Kiedy należy zatwierdzać z SQLAlchemy przy użyciu pętli for?

for item in items: 
    db.session.add(item) 
    db.session.commit() 

lub

for item in items: 
    db.session.add(item) 
db.session.commit() 
+1

Ile operacji wykonujesz w sumie? Czy wymagają dużej ilości zasobów? O ile nie ma powodu, dla którego nie chciałbyś popełnić po każdym, nie rozumiem, dlaczego nie chcesz zawsze używać # 1. – woemler

Odpowiedz

4

Myślę, że drugie rozwiązanie jest lepsze, ale to zależy od tego, jak został skonfigurowany sesji. W szczególności ustawienia autoflush i autocommit. Powinieneś także używać silnika, który ma dobre wsparcie dla transakcji, takich jak innodb.

Zakładając, że autocommit i autoflush są wyłączone, to spłukiwałbyś swoją wstawkę do serwera, wykonując wcześniejszą transakcję, a następnie tworząc kolejną transakcję na każdej iteracji, która tworzy dużo niepotrzebnej pracy zarówno w SQLAlchemy jak i MySQL.

Polecam używanie add_all, jeśli masz prostą listę elementów do dodania, jak w twoim przykładzie, w przeciwnym razie, jeśli potrzebujesz pętli, zdecydowanie zastosuj commit poza pętlą.

http://docs.sqlalchemy.org/en/latest/orm/session.html#sqlalchemy.orm.session.Session.add_all

db.session.add_all(items) 
db.session.commit() 

Dodatkowa uwaga, jeśli coś się nie udać część sposób przez pętlę transakcja będzie wycofać pisze tylko uprzedniej popełnić w pętli, która prawdopodobnie nie jest to, co chcesz, jeśli używają transakcji. Na przykład tylko połowa twoich pozycji na liście może zostać zapisana do bazy danych, jeśli błąd wystąpi w połowie twojej pętli. Natomiast wywoływanie commit poza pętlą gwarantuje, że twoja pętla została zakończona i będzie ALL commit lub ALL wycofany.