Mysql
 sql >> Datenbank >  >> RDS >> Mysql

SQLAlchemy BEI DOPPELTER SCHLÜSSELAKTUALISIERUNG

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