ON DUPLICATE KEY UPDATE
après la version 1.2 pour MySQL
Cette fonctionnalité est désormais intégrée à SQLAlchemy pour MySQL uniquement. La réponse de somada141 ci-dessous a la meilleure solution :un>
ON DUPLICATE KEY UPDATE
dans l'instruction SQL
Si vous voulez que le SQL généré inclue réellement ON DUPLICATE KEY UPDATE
, le moyen le plus simple consiste à utiliser un @compiles
décorateur.
Le code (lié à un bon fil de discussion sur le sujet sur reddit ) pour un exemple peut être trouvé sur 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)
Mais notez que dans cette approche, vous devez créer manuellement le fichier append_string. Vous pourriez probablement modifier la fonction append_string afin qu'elle change automatiquement la chaîne d'insertion en une insertion avec la chaîne 'ON DUPLICATE KEY UPDATE', mais je ne vais pas le faire ici par paresse.
ON DUPLICATE KEY UPDATE
fonctionnalité au sein de l'ORM
SQLAlchemy ne fournit pas d'interface pour ON DUPLICATE KEY UPDATE
ou MERGE
ou toute autre fonctionnalité similaire dans sa couche ORM. Néanmoins, il a le session.merge()
fonction qui peut répliquer la fonctionnalité uniquement si la clé en question est une clé primaire .
session.merge(ModelObject)
vérifie d'abord si une ligne avec la même valeur de clé primaire existe en envoyant un SELECT
requête (ou en la recherchant localement). Si c'est le cas, il définit un indicateur quelque part indiquant que ModelObject est déjà dans la base de données et que SQLAlchemy doit utiliser un UPDATE
requête. Notez que la fusion est un peu plus compliquée que cela, mais elle reproduit bien la fonctionnalité avec les clés primaires.
Mais que se passe-t-il si vous voulez ON DUPLICATE KEY UPDATE
fonctionnalité avec une clé non primaire (par exemple, une autre clé unique) ? Malheureusement, SQLAlchemy n'a pas une telle fonction. Au lieu de cela, vous devez créer quelque chose qui ressemble à get_or_create()
de Django . Une autre réponse StackOverflow le couvre
, et je vais juste en coller une version de travail modifiée ici pour plus de commodité.
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