基本的に行っているのは、パフォーマンスを最適化するためにORMをバイパスすることです。したがって、「ORMが実行している作業を複製している」ことに驚かないでください。これは、まさにそれが必要なことだからです。
このような一括更新を行う必要がある場所がたくさんない限り、魔法のイベントアプローチには反対することをお勧めします。明示的なクエリを書くだけの方がはるかに簡単です。
私がお勧めするのは、ORMの代わりにSQLAlchemyCoreを使用して更新を行うことです。
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()