sql >> Base de Datos >  >> RDS >> Mysql

SQLAlchemy EN ACTUALIZACIÓN DE CLAVE DUPLICADA

ON DUPLICATE KEY UPDATE publicar la versión 1.2 para MySQL

Esta funcionalidad ahora está integrada en SQLAlchemy solo para MySQL. La respuesta de somada141 a continuación tiene la mejor solución:https://stackoverflow.com/a/48373874/319066

ON DUPLICATE KEY UPDATE en la instrucción SQL

Si desea que el SQL generado incluya realmente ON DUPLICATE KEY UPDATE , la forma más sencilla implica usar un @compiles decorador.

El código (enlazado desde un buen hilo sobre el tema en reddit ) para ver un ejemplo, se puede encontrar en 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)

Pero tenga en cuenta que en este enfoque, debe crear manualmente append_string. Probablemente podría cambiar la función append_string para que cambie automáticamente la cadena de inserción en una inserción con la cadena 'ON ACTUALIZACIÓN DE CLAVE DUPLICADA', pero no voy a hacer eso aquí debido a la pereza.

ON DUPLICATE KEY UPDATE funcionalidad dentro del ORM

SQLAlchemy no proporciona una interfaz para ON DUPLICATE KEY UPDATE o MERGE o cualquier otra funcionalidad similar en su capa ORM. Sin embargo, tiene el session.merge() función que puede replicar la funcionalidad solo si la clave en cuestión es una clave principal .

session.merge(ModelObject) primero comprueba si existe una fila con el mismo valor de clave principal enviando un SELECT consulta (o buscándola localmente). Si lo hace, establece una marca en algún lugar que indica que ModelObject ya está en la base de datos y que SQLAlchemy debe usar UPDATE consulta. Tenga en cuenta que fusionar es un poco más complicado que esto, pero replica bien la funcionalidad con claves principales.

Pero, ¿qué sucede si desea ON DUPLICATE KEY UPDATE? funcionalidad con una clave no primaria (por ejemplo, otra clave única)? Desafortunadamente, SQLAlchemy no tiene esa función. En su lugar, debe crear algo que se asemeje a get_or_create() de Django. . Otra respuesta de StackOverflow lo cubre , y simplemente pegaré una versión funcional modificada aquí para mayor comodidad.

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