sql >> Databasteknik >  >> RDS >> Mysql

SQLAlchemy PÅ DUBLIKATNYCKELUPPDATERING

PÅ DUBLIKAT UPPDATERING AV NYCKEL post version-1.2 för MySQL

Denna funktion är nu inbyggd i SQLAlchemy endast för MySQL. Somada141s svar nedan har den bästa lösningen:https://stackoverflow.com/a/48373874/319066

PÅ DUBLIKAT UPPDATERING AV NYCKEL i SQL-satsen

Om du vill att den genererade SQL-koden faktiskt ska inkludera ON DUPLICATE KEY UPDATE , det enklaste sättet är att använda en @compiles dekoratör.

Koden (länkad från en bra tråd om ämnet på reddit ) för ett exempel kan hittas på 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)

Men observera att i detta tillvägagångssätt måste du manuellt skapa append_string. Du kan förmodligen ändra append_string-funktionen så att den automatiskt ändrar infogningssträngen till en infogning med 'ON DUPLICATE KEY UPDATE'-strängen, men jag tänker inte göra det här på grund av lathet.

PÅ DUBLIKAT UPPDATERING AV NYCKEL funktionalitet inom ORM

SQLAlchemy tillhandahåller inget gränssnitt för PÅ DUBLIKAT UPPDATERING AV NYCKEL eller SAMMANFATTNING eller någon annan liknande funktionalitet i dess ORM-lager. Ändå har den session.merge() funktion som kan replikera funktionen endast om nyckeln i fråga är en primärnyckel .

session.merge(ModelObject) kontrollerar först om en rad med samma primärnyckelvärde finns genom att skicka en SELECT fråga (eller genom att leta upp det lokalt). Om den gör det sätter den en flagga någonstans som indikerar att ModelObject redan finns i databasen och att SQLAlchemy ska använda en UPDATE fråga. Observera att sammanslagning är ganska lite mer komplicerat än så här, men det replikerar funktionaliteten väl med primärnycklar.

Men vad händer om du vill ha PÅ DUBLIKAT UPPDATERING AV NYCKEL funktionalitet med en icke-primär nyckel (till exempel en annan unik nyckel)? Tyvärr har SQLAlchemy ingen sådan funktion. Istället måste du skapa något som liknar Djangos get_or_create() . Ett annat StackOverflow-svar täcker det , och jag kommer bara att klistra in en modifierad, fungerande version av den här för enkelhetens skull.

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


  1. En bra referens för Oracle PL/SQL

  2. Fel:Ingen modul med namnet psycopg2.extensions

  3. Entity Framework och flera scheman

  4. Spring JDBC-stöd och stor datauppsättning