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