Mysql
 sql >> Base de données >  >> RDS >> Mysql

SQLAlchemy SUR LA MISE À JOUR DE LA CLÉ EN DOUBLE

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