Gibt es eine elegante Möglichkeit, ein INSERT ... ON DUPLICATE KEY UPDATE
in SQLAlchemy durchzuführen? Ich meine etwas mit einer Syntax ähnlich wie inserter.insert().execute(list_of_dictionaries)
?
Antworten
Zu viele Anzeigen?Es hängt von dir ab. Wenn du ersetzen möchtest, gib OR REPLACE
in den Präfixen an
def bulk_insert(self,objects,table):
#table: Ihre Tabellenklasse und objects sind eine Liste von Dictionaries [{col1:val1, col2:vale}]
for counter,row in enumerate(objects):
inserter = table.__table__.insert(prefixes=['OR IGNORE'], values=row)
try:
self.db.execute(inserter)
except Exception as E:
print E
if counter % 100 == 0:
self.db.commit()
self.db.commit()
Hier kann das Commit-Intervall geändert werden, um den Prozess zu beschleunigen oder zu verlangsamen
Die anderen Antworten haben das bereits abgedeckt, aber ich dachte, ich würde ein weiteres gutes Beispiel für mysql erwähnen, das ich in diesem Gist gefunden habe. Dies beinhaltet auch die Verwendung von LAST_INSERT_ID
, was je nach Ihren innodb auto increment Einstellungen und ob Ihre Tabelle einen eindeutigen Schlüssel hat, nützlich sein kann. Ich kopiere den Code hier zur einfachen Referenz, aber bitte geben Sie dem Autor einen Stern, wenn Sie ihn nützlich finden.
from app import db
from sqlalchemy import func
from sqlalchemy.dialects.mysql import insert
def upsert(model, insert_dict):
"""model kann ein db.Model oder ein table() sein, insert_dict sollte einen primären oder eindeutigen Schlüssel enthalten."""
inserted = insert(model).values(**insert_dict)
upserted = inserted.on_duplicate_key_update(
id=func.LAST_INSERT_ID(model.id), **{k: inserted.inserted[k]
for k, v in insert_dict.items()})
res = db.engine.execute(upserted)
return res.lastrowid
Da keines dieser Lösungen besonders elegant wirkt. Ein brute-force-Weg besteht darin, abzufragen, ob die Zeile existiert. Wenn dies der Fall ist, löschen Sie die Zeile und fügen Sie sie dann ein, andernfalls fügen Sie sie einfach ein. Natürlich entsteht ein gewisser Overhead, aber es basiert nicht auf der Modifikation des Roh-SQL und funktioniert auch bei Nicht-ORM-Elementen.
- See previous answers
- Weitere Antworten anzeigen