53 Stimmen

SQLAlchemy BEI DUPLIKAT VORHANDENEM SCHLÜSSEL AKTUALISIEREN

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

1voto

Manoj Sahu Punkte 2576

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

1voto

totalhack Punkte 1650

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

0voto

Shoeb Ahmed Mogal Punkte 117

Ich habe einfach SQL verwendet wie:

insert_stmt = "REPLACE INTO tablename (column1, column2) VALUES (:column_1_bind, :columnn_2_bind) "
session.execute(insert_stmt, data)

-1voto

Peter Lonjers Punkte 205

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.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X