ON DUPLICATE KEY UPDATE
post versie 1.2 voor MySQL
Deze functionaliteit is nu alleen voor MySQL in SQLAlchemy ingebouwd. somada141's antwoord hieronder heeft de beste oplossing:https://stackoverflow.com/a/48373874/319066
ON DUPLICATE KEY UPDATE
in de SQL-instructie
Als u wilt dat de gegenereerde SQL daadwerkelijk ON DUPLICATE KEY UPDATE
. bevat , de eenvoudigste manier is het gebruik van een @compiles
binnenhuisarchitect.
De code (gekoppeld vanuit een goede thread over het onderwerp op reddit ) voor een voorbeeld is te vinden op 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)
Maar merk op dat u in deze benadering handmatig de append_string moet maken. Je zou waarschijnlijk de append_string functie kunnen veranderen zodat deze automatisch de insert string verandert in een insert met 'ON DUPLICATE KEY UPDATE' string, maar ik ga dat hier niet doen vanwege luiheid.
ON DUPLICATE KEY UPDATE
functionaliteit binnen de ORM
SQLAlchemy biedt geen interface voor ON DUPLICATE KEY UPDATE
of MERGE
of enige andere vergelijkbare functionaliteit in zijn ORM-laag. Niettemin heeft het de session.merge()
functie die de functionaliteit kan repliceren alleen als de betreffende sleutel een primaire sleutel is .
session.merge(ModelObject)
controleert eerst of een rij met dezelfde primaire sleutelwaarde bestaat door een SELECT
. te sturen query (of door het lokaal op te zoeken). Als dit het geval is, wordt er ergens een vlag gezet die aangeeft dat ModelObject al in de database staat en dat SQLAlchemy een UPDATE
moet gebruiken vraag. Merk op dat samenvoegen een stuk ingewikkelder is dan dit, maar het repliceert de functionaliteit goed met primaire sleutels.
Maar wat als u ON DUPLICATE KEY UPDATE
. wilt? functionaliteit met een niet-primaire sleutel (bijvoorbeeld een andere unieke sleutel)? Helaas heeft SQLAlchemy zo'n functie niet. In plaats daarvan moet je iets maken dat lijkt op Django's get_or_create()
. Een ander StackOverflow-antwoord dekt het
, en voor het gemak plak ik hier een aangepaste, werkende versie ervan.
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