To, co v podstatě děláte, je obcházení ORM za účelem optimalizace výkonu. Proto se nedivte, že „replikujete práci, kterou ORM dělá“, protože to je přesně to, co musíte udělat.
Pokud nemáte mnoho míst, kde potřebujete provádět hromadné aktualizace, jako je tato, doporučil bych proti přístupu magických událostí; jednoduché psaní explicitních dotazů je mnohem jednodušší.
Doporučuji k provedení aktualizace použít SQLAlchemy Core místo 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()