Używam Flask-SQLAlchemy do wykonania raczej dużej wkładki zbiorczej z 60 tys. Wierszy. Mam również wiele relacji do wielu na tym stole, więc nie mogę do tego użyć db.engine.execute
. Przed wstawieniem muszę znaleźć podobne elementy w bazie danych i zmienić wstawkę na aktualizację, jeśli znajdzie się zduplikowany element.Wkładki masowe z kolbą-SQLAlchemy
Mogę wcześniej wykonać tę kontrolę, a następnie wykonać wkładkę zbiorczą za pomocą db.engine.execute
, ale potrzebuję klucz podstawowy rzędu po wstawieniu.
Obecnie robię db.session.add()
i db.session.commit()
na każdej wkładce, a otrzymuję marne 3-4 wkładki na sekundę.
Uruchomiłem profilera, aby zobaczyć, gdzie jest wąskie gardło, i wydaje się, że db.session.commit()
zajmuje 60% czasu.
Czy jest jakiś sposób, który pozwoliłby mi przyspieszyć tę operację, być może poprzez zgrupowanie zatwierdzeń, ale które przywróciłyby mi klucze podstawowe?
To co moje modele wygląda następująco:
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))
Moja operacja wkładka jest prowadzony tak:
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()
Zmiana 'db.session.commit()' na 'db.session.flush()' 'i wtedy robi db.session.commit()' na koniec daje ja 10-12 wstawek na sekundę, zdecydowanie szybciej, ale nie za dużo. –