PÅ DUBLIKAT NØGLEOPDATERING
post version-1.2 til MySQL
Denne funktionalitet er nu kun indbygget i SQLAlchemy til MySQL. Somada141's svar nedenfor har den bedste løsning:https://stackoverflow.com/a/48373874/319066
PÅ DUBLIKAT NØGLEOPDATERING
i SQL-sætningen
Hvis du ønsker, at den genererede SQL faktisk skal inkludere ON DUPLICATE KEY UPDATE
, den enkleste måde involverer at bruge en @compiles
dekoratør.
Koden (linket fra en god tråd om emnet på reddit ) for et eksempel kan findes 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 bemærk, at i denne tilgang skal du manuelt oprette append_string. Du kunne sikkert ændre append_string-funktionen, så den automatisk ændrer insert-strengen til en insert med 'ON DUPLICATE KEY UPDATE'-streng, men det vil jeg ikke gøre her på grund af dovenskab.
PÅ DUBLIKAT NØGLEOPDATERING
funktionalitet i ORM
SQLAlchemy giver ikke en grænseflade til ON DUPLICATE KEY UPDATE
eller FLET
eller enhver anden lignende funktionalitet i dets ORM-lag. Ikke desto mindre har den session.merge()
funktion, der kan replikere funktionaliteten kun hvis den pågældende nøgle er en primær nøgle .
session.merge(ModelObject)
kontrollerer først, om der findes en række med samme primærnøgleværdi ved at sende en SELECT
forespørgsel (eller ved at slå den op lokalt). Hvis den gør det, sætter den et flag et sted, der indikerer, at ModelObject allerede er i databasen, og at SQLAlchemy skal bruge en OPDATERING
forespørgsel. Bemærk, at fletning er en del mere kompliceret end dette, men det replikerer funktionaliteten godt med primærnøgler.
Men hvad hvis du vil have PÅ DUBLIKAT NØGLEOPDATERING
funktionalitet med en ikke-primær nøgle (f.eks. en anden unik nøgle)? Desværre har SQLAlchemy ikke nogen sådan funktion. I stedet skal du oprette noget, der ligner Djangos get_or_create()
. Et andet StackOverflow-svar dækker det
, og jeg indsætter bare en ændret, fungerende version af den her for nemheds skyld.
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