sto usando Flask-SQLAlchemy fare una piuttosto grande inserimento di massa di 60k righe. Ho anche una relazione molti-a-molti su questo tavolo, quindi non posso usare db.engine.execute
per questo. Prima di inserire, ho bisogno di trovare elementi simili nel database e di modificare l'inserimento in un aggiornamento se viene trovato un elemento duplicato.inserti Bulk con Flask-SQLAlchemy
Potrei fare questo controllo in anticipo, e poi fare un inserto di massa via db.engine.execute
, ma ho bisogno della chiave primaria della riga al momento dell'inserimento.
Attualmente, sto facendo un db.session.add()
e db.session.commit()
su ogni inserto e ottengo un misero 3-4 inserti al secondo.
Ho eseguito un profiler per vedere dove si trova il collo di bottiglia, e sembra che il db.session.commit()
stia prendendo il 60% delle volte.
C'è qualche modo che mi permettesse di fare questa operazione più veloce, forse per gruppo si impegna, ma che mi avrebbe dato le chiavi primarie indietro?
Questo è ciò che sembra i miei modelli come:
class Item(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(1024), nullable=True)
created = db.Column(db.DateTime())
tags_relationship = db.relationship('Tag', secondary=tags, backref=db.backref('items', lazy='dynamic'))
tags = association_proxy('tags_relationship', 'text')
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(255))
La mia operazione di inserimento è gestito in questo modo:
for item in items:
if duplicate:
update_existing_item
else:
x = Item()
x.title = "string"
x.created = datetime.datetime.utcnow()
for tag in tags:
if not tag_already_exists:
y = Tag()
y.text = "tagtext"
x.tags_relationship.append(y)
db.session.add(y)
db.session.commit()
else:
x.tags_relationship.append(existing_tag)
db.session.add(x)
db.session.commit()
Modifica 'db.session.commit()' a 'db.session.flush()' e poi facendo 'db.session.commit()' alla fine dà me 10-12 inserti al secondo, più veloce sicuramente, ma non di molto. –