Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

SQLAlchemy NA ATUALIZAÇÃO DE CHAVE DUPLICADA

NA ATUALIZAÇÃO DE CHAVE DUPLICADA post versão 1.2 para MySQL


Essa funcionalidade agora está incorporada ao SQLAlchemy apenas para MySQL. A resposta de somada141 abaixo tem a melhor solução:https://stackoverflow.com/a/48373874/319066

NA ATUALIZAÇÃO DE CHAVE DUPLICADA na instrução SQL


Se você quiser que o SQL gerado inclua realmente ON DUPLICATE KEY UPDATE , a maneira mais simples envolve usar um @compiles decorador.

O código (vinculado de um bom tópico sobre o assunto no reddit ) para um exemplo pode ser encontrado no 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)

Mas observe que nesta abordagem, você precisa criar manualmente o append_string. Você provavelmente poderia alterar a função append_string para que ela altere automaticamente a string de inserção em uma inserção com a string 'ON DUPLICATE KEY UPDATE', mas não vou fazer isso aqui devido à preguiça.

NA ATUALIZAÇÃO DE CHAVE DUPLICADA funcionalidade dentro do ORM


SQLAlchemy não fornece uma interface para ON DUPLICATE KEY UPDATE ou MERGE ou qualquer outra funcionalidade semelhante em sua camada ORM. No entanto, tem o session.merge() função que pode replicar a funcionalidade somente se a chave em questão for uma chave primária .

session.merge(ModelObject) primeiro verifica se existe uma linha com o mesmo valor de chave primária enviando um SELECT consulta (ou procurando localmente). Se isso acontecer, ele define um sinalizador em algum lugar indicando que ModelObject já está no banco de dados e que SQLAlchemy deve usar um UPDATE inquerir. Observe que a mesclagem é um pouco mais complicada do que isso, mas replica bem a funcionalidade com chaves primárias.

Mas e se você quiser ON DUPLICATE KEY UPDATE funcionalidade com uma chave não primária (por exemplo, outra chave exclusiva)? Infelizmente, o SQLAlchemy não possui essa função. Em vez disso, você precisa criar algo que se assemelhe ao get_or_create() do Django . Outra resposta do StackOverflow cobre isso , e vou colar uma versão modificada e funcional dele aqui por conveniência.
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