ON DUPLICATE KEY UPDATE
Post-Version-1.2 für MySQL
Diese Funktionalität ist jetzt nur für MySQL in SQLAlchemy integriert. Die Antwort von somada141 unten hat die beste Lösung:https://stackoverflow.com/a/48373874/319066
ON DUPLICATE KEY UPDATE
in der SQL-Anweisung
Wenn Sie möchten, dass das generierte SQL tatsächlich ON DUPLICATE KEY UPDATE
enthält , ist der einfachste Weg die Verwendung eines @compiles
Dekorateur.
Der Code (verlinkt von einem guten Thread zum Thema auf reddit ) für ein Beispiel finden Sie auf github :
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def append_string(insert, compiler, **kw):
s = compiler.visit_insert(insert, **kw)
if 'append_string' in insert.kwargs:
return s + " " + insert.kwargs['append_string']
return s
my_connection.execute(my_table.insert(append_string = 'ON DUPLICATE KEY UPDATE foo=foo'), my_values)
Beachten Sie jedoch, dass Sie bei diesem Ansatz die append_string manuell erstellen müssen. Sie könnten wahrscheinlich die Funktion append_string so ändern, dass sie den Insert-String automatisch in einen Insert-String mit 'ON DUPLICATE KEY UPDATE' ändert, aber ich werde das hier aus Faulheit nicht tun.
ON DUPLICATE KEY UPDATE
Funktionalität innerhalb des ORM
SQLAlchemy bietet keine Schnittstelle zu ON DUPLICATE KEY UPDATE
oder MERGE
oder jede andere ähnliche Funktionalität in seiner ORM-Schicht. Trotzdem hat es den session.merge()
Funktion, die die Funktionalität nur dann replizieren kann, wenn der fragliche Schlüssel ein Primärschlüssel ist .
session.merge(ModelObject)
überprüft zuerst, ob eine Zeile mit demselben Primärschlüsselwert existiert, indem ein SELECT
gesendet wird Abfrage (oder durch lokales Nachschlagen). Wenn dies der Fall ist, wird irgendwo ein Flag gesetzt, das anzeigt, dass sich ModelObject bereits in der Datenbank befindet und dass SQLAlchemy ein UPDATE
verwenden sollte Anfrage. Beachten Sie, dass das Zusammenführen etwas komplizierter ist, aber es repliziert die Funktionalität gut mit Primärschlüsseln.
Aber was, wenn Sie ON DUPLICATE KEY UPDATE
wollen Funktionalität mit einem Nicht-Primärschlüssel (z. B. einem anderen eindeutigen Schlüssel)? Leider hat SQLAlchemy keine solche Funktion. Stattdessen müssen Sie etwas erstellen, das Djangos get_or_create()
ähnelt . Eine weitere StackOverflow-Antwort deckt es ab
, und ich füge der Einfachheit halber einfach eine modifizierte, funktionierende Version davon hier ein.
def get_or_create(session, model, defaults=None, **kwargs):
instance = session.query(model).filter_by(**kwargs).first()
if instance:
return instance
else:
params = dict((k, v) for k, v in kwargs.iteritems() if not isinstance(v, ClauseElement))
if defaults:
params.update(defaults)
instance = model(**params)
return instance