51 votes

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

Existe-t-il un moyen élégant de faire un INSERT ... ON DUPLICATE KEY UPDATE dans SQLAlchemy ? Je veux dire quelque chose avec une syntaxe similaire à inserter.insert().execute(list_of_dictionaries) ?

37voto

somada141 Points 379

Je dois mentionner que depuis la sortie de v1.2, « noyau » du SQLAlchemy a une solution à ce qui précède avec qui est construit et peut être vu sous ici (extrait copié ci - dessous):

 from sqlalchemy.dialects.mysql import insert

insert_stmt = insert(my_table).values(
    id='some_existing_id',
    data='inserted value')

on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
    data=insert_stmt.inserted.data,
    status='U'
)

conn.execute(on_duplicate_key_stmt)

2voto

sheba Points 485

Sur la base de la réponse de phsource , et pour le cas d'utilisation spécifique d'utilisation de MySQL et de remplacement complet des données pour la même clé sans exécuter une DELETE , on peut utiliser l'insert décoré @compiles expression:

 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 insert.kwargs.get('on_duplicate_key_update'):
        fields = s[s.find("(") + 1:s.find(")")].replace(" ", "").split(",")
        generated_directive = ["{0}=VALUES({0})".format(field) for field in fields]
        return s + " ON DUPLICATE KEY UPDATE " + ",".join(generated_directive)
    return s

1voto

Manoj Sahu Points 1437

Cela dépend de vous. Si vous voulez remplacer alors passez OR REPLACE dans les préfixes

   def bulk_insert(self,objects,table):
    #table: Your table class and objects are list of dictionary [{col1:val1, col2:vale}] 
    for counter,row in enumerate(objects):
        inserter = table.__table__.insert(prefixes=['OR IGNORE'], values=row)
        try:
            self.db.execute(inserter)
        except Exception as E:
            print E
        if counter % 100 == 0:
            self.db.commit()                    
    self.db.commit()

Ici, l'intervalle de validation peut être modifié pour accélérer ou ralentir

0voto

Frank He Points 518

J'ai une solution plus simple :

 from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Insert

@compiles(Insert)
def replace_string(insert, compiler, **kw):
    s = compiler.visit_insert(insert, **kw)
    s = s.replace("INSERT INTO", "REPLACE INTO")
    return s

my_connection.execute(my_table.insert(replace_string=""), my_values)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X