Mysql
 sql >> Datenbank >  >> RDS >> Mysql

SQLAlchemy-Massenaktualisierungsstrategien

Was Sie im Wesentlichen tun, ist das Umgehen des ORM, um die Leistung zu optimieren. Seien Sie daher nicht überrascht, dass Sie „die Arbeit des ORM replizieren“, denn das ist genau das, was Sie tun müssen.

Wenn Sie nicht viele Orte haben, an denen Sie Massenaktualisierungen wie diese durchführen müssen, würde ich gegen den magischen Event-Ansatz raten; Das einfache Schreiben der expliziten Abfragen ist viel einfacher.

Was ich empfehle, ist die Verwendung von SQLAlchemy Core anstelle des ORM, um das Update durchzuführen:

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()