Това, което по същество правите, е да заобиколите ORM, за да оптимизирате производителността. Затова не се учудвайте, че „възпроизвеждате работата, която върши ORM“, защото точно това трябва да направите.
Освен ако нямате много места, където трябва да правите групови актуализации като това, бих препоръчал да не използвате подхода на магическото събитие; простото писане на изричните заявки е много по-лесно.
Това, което препоръчвам да направите, е да използвате SQLAlchemy Core вместо ORM, за да извършите актуализацията:
ledger = Table("ledger", db.metadata,
Column("wallet_id", Integer, primary_key=True),
Column("new_balance", Float),
prefixes=["TEMPORARY"],
)
wallets = db_session.query(Wallet).all()
# figure out new balances
balance_map = {}
for w in wallets:
balance_map[w.id] = calculate_new_balance(w)
# create temp table with balances we need to update
ledger.create(bind=db.session.get_bind())
# insert update data
db.session.execute(ledger.insert().values([{"wallet_id": k, "new_balance": v}
for k, v in balance_map.items()])
# perform update
db.session.execute(Wallet.__table__
.update()
.values(balance=ledger.c.new_balance)
.where(Wallet.__table__.c.id == ledger.c.wallet_id))
# drop temp table
ledger.drop(bind=db.session.get_bind())
# commit changes
db.session.commit()