2016-05-03 11 views
1

Ich muss Millionen von Zeile in MySQL aktualisieren. Ich verwende zur Zeit for-Schleife, um eine Abfrage auszuführen. Um das Update schneller zu machen, möchte ich executemany() von Python MySQL Connector verwenden, so dass ich in Chargen mit einer einzigen Abfrage für jeden Batch aktualisieren kann.Bulk Update MySql mit Python

+1

Nizza .. aber ich sehe keine Frage? – Marco

+0

Grundsätzlich möchte ich Executemany für das Update in Python verwenden. Ist es möglich ? – keshaw

+0

Ich denke nicht – Marco

Antwort

1

Ich glaube nicht, mysqldb hat eine Art und Weise zu einem Zeitpunkt mehr UPDATE-Abfragen zu verarbeiten.

Sie können jedoch eine INSERT-Abfrage mit ON DUPLICATE KEY UPDATE-Bedingung am Ende verwenden.

Ich schrieb das folgende Beispiel für die Benutzerfreundlichkeit und Lesbarkeit.

import MySQLdb 

def update_many(data_list=None, mysql_table=None): 
    """ 
    Updates a mysql table with the data provided. If the key is not unique, the 
    data will be inserted into the table. 

    The dictionaries must have all the same keys due to how the query is built. 

    Param: 
     data_list (List): 
      A list of dictionaries where the keys are the mysql table 
      column names, and the values are the update values 
     mysql_table (String): 
      The mysql table to be updated. 
    """ 

    # Connection and Cursor 
    conn = MySQLdb.connect('localhost', 'jeff', 'atwood', 'stackoverflow') 
    cur = conn.cursor() 

    query = "" 
    values = [] 

    for data_dict in data_list: 

     if not query: 
      columns = ', '.join('`{0}`'.format(k) for k in data_dict) 
      duplicates = ', '.join('{0}=VALUES({0})'.format(k) for k in data_dict) 
      place_holders = ', '.join('%s'.format(k) for k in data_dict) 
      query = "INSERT INTO {0} ({1}) VALUES ({2})".format(mysql_table, columns, place_holders) 
      query = "{0} ON DUPLICATE KEY UPDATE {1}".format(query, duplicates) 

     v = data_dict.values() 
     values.append(v) 

    try: 
     cur.executemany(query, values) 
    except MySQLdb.Error, e: 
     try: 
      print"MySQL Error [%d]: %s" % (e.args[0], e.args[1]) 
     except IndexError: 
      print "MySQL Error: %s" % str(e) 

     conn.rollback() 
     return False 

    conn.commit() 
    cur.close() 
    conn.close() 

Erklärung der Einzeiler

columns = ', '.join('`{}`'.format(k) for k in data_dict) 

ist die gleiche wie

column_list = [] 
for k in data_dict: 
    column_list.append(k) 
columns = ", ".join(columns) 

Hier ist ein Beispiel für die Nutzung

test_data_list = [] 
test_data_list.append({'id' : 1, 'name' : 'Marco', 'articles' : 1 }) 
test_data_list.append({'id' : 2, 'name' : 'Keshaw', 'articles' : 8 }) 
test_data_list.append({'id' : 3, 'name' : 'Wes', 'articles' : 0 }) 

update_many(data_list=test_data_list, mysql_table='writers') 

Abfrage Ausgabe

INSERT INTO writers (`articles`, `id`, `name`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE articles=VALUES(articles), id=VALUES(id), name=VALUES(name) 

Werte Ausgang

[[1, 1, 'Marco'], [8, 2, 'Keshaw'], [0, 3, 'Wes']] 
+0

Yeah Mysql unterstützt keine Massenaktualisierung. – keshaw

+0

Der obige Code ermöglicht Ihnen das Bulk-Update. –

1

Vielleicht kann dies helfen How to update multiple rows with single MySQL query in python?

cur.executemany("UPDATE Writers SET Name = %s WHERE Id = %s ", 
    [("new_value" , "3"),("new_value" , "6")]) 
conn.commit() 
+0

Nein Es funktioniert nicht. Es funktioniert nur für das Einfügen nicht für das Update – keshaw

+0

@user Warum ist es "nicht funktioniert"? Was ist der Fehler? –

+0

Kein Fehler und keine Aktualisierung – keshaw