2015-01-12 13 views
6

Ho uno script Python principale che si collega a un database MySQL e ne estrae pochi record. In base al risultato restituito, inizia come molti thread (istanze di classe) di quanti record vengono afferrati. Ogni thread dovrebbe tornare al database e aggiornare un'altra tabella impostando un flag di stato su uno stato diverso ("processo avviato").Come gestire le connessioni MySQL con il multithreading Python

Per ottenere questo ho cercato di:

1.) Far passare la connessione al database per tutte le discussioni 2.) Aprire una nuova connessione al database da ogni thread

ma nessuno di loro stavano lavorando.

Potrei eseguire il mio aggiornamento senza alcun problema in entrambi i casi utilizzando try/except, ma la tabella MySQL non è stata aggiornata e non è stato generato alcun errore. Ho usato il commit in entrambi i casi.

La mia domanda sarebbe come gestire le connessioni MySQL in questo caso?

aggiornamento sulla base dei primi commenti:

MAIN SCRIPT 
----------- 

#Connecting to DB 
db = MySQLdb.connect(host = db_host, 
         db = db_db, 
         port = db_port, 
         user = db_user, 
         passwd = db_password, 
         charset='utf8') 

# Initiating database cursor 
cur = db.cursor() 

# Fetching records for which I need to initiate a class instance 

cur.execute('SELECT ...') 

for row in cur.fetchall() : 
    # Initiating new instance, appending it to a list and 
    # starting all of them 



CLASS WHICH IS INSTANTIATED 
--------------------------- 

# Connecting to DB again. I also tried to pass connection 
# which has been opened in the main script but it did not 
# work either. 

db = MySQLdb.connect(host = db_host, 
         db = db_db, 
         port = db_port, 
         user = db_user, 
         passwd = db_password, 
         charset='utf8') 

# Initiating database cursor 
cur_class = db.cursor() 
cur.execute('UPDATE ...') 
db.commit() 
+0

difficile dire qualcosa senza sapere come ci si collega al DB e come si fa a implementare gli aggiornamenti. – Ashalynd

+0

Non capisco completamente la tua domanda. Il caso più semplice funziona, come il Python a thread singolo si connette a mysql e aggiorna una tabella? – qqibrow

+0

@Ashalynd Grazie per aver dedicato del tempo! E scusa ma ero AFK. Ho aggiornato la mia domanda con uno snipet di codice dai miei codici principali e di classe. Questo è il modo in cui avvio le istanze e apro le connessioni al database. Ho cercato di rilevare l'errore durante l'apertura della connessione e l'esecuzione della query dall'istanza con try/tranne senza fortuna. – g0m3z

risposta

3

Sembra che non ci siano problemi con il mio codice ma con la mia versione di MySQL. Sto usando la versione community standard di MySQL e basata sulla documentazione ufficiale trovata here:

Il plug-in del pool di thread è una funzionalità commerciale. Non è incluso nelle distribuzioni della comunità MySQL.

Sto per eseguire l'aggiornamento a MariaDB per risolvere questo problema.

9

Ecco un esempio utilizzando il multithreading affare mysql in Python, non so vostra tavola e dei dati, così, basta modificare il codice può help:

import threading 
import time 
import MySQLdb 

Num_Of_threads = 5 

class myThread(threading.Thread): 

    def __init__(self, conn, cur, data_to_deal): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.conn = conn 
     self.cur = cur 
     self.data_to_deal 

    def run(self): 

     # add your sql 
     sql = 'insert into table id values ({0});' 
     for i in self.data_to_deal: 
      self.cur.execute(sql.format(i)) 
      self.conn.commit() 

threads = [] 
data_list = [1,2,3,4,5] 

for i in range(Num_Of_threads): 
    conn = MySQLdb.connect(host='localhost',user='root',passwd='',db='') 
    cur = conn.cursor() 
    new_thread = myThread(conn, cur, data_list[i]) 

for th in threads: 
    th.start() 

for t in threads: 
    t.join() 
+0

Ci scusiamo per la mia risposta in ritardo. Riferendosi al tuo esempio sopra ho la mia classe e il mio script principale in due file diversi. Questo non dovrebbe essere un problema, immagino. Un'altra cosa che faccio in modo diverso è che non passo il mio data_list al mio thread perché ho bisogno del mio thread per interrogare i dati dal mio database al volo. Quindi, quello che faccio è: 1.) Aprire una connessione al database (script principale) 2.) Record di query (script principale) 3.) Avviare tutte le istanze di classe di molti record che ho (script principale) 4.) Prova ad aggiornare un record di tabella in DB da ogni istanza (istanza di classe) – g0m3z

1

Sembra che mysql 5.7 supporti il ​​multithreading.

Come hai provato in precedenza, assicurati assolutamente di passare la connessione all'interno del def worker(). definire le connessioni a livello mondiale è stato il mio errore

Qui di codice di esempio che consente di stampare 10 record tramite 5 fili, 5 volte

import MySQLdb 
import threading 


def write_good_proxies():  
    local_db = MySQLdb.connect("localhost","username","PassW","DB", port=3306) 
    local_cursor = local_db.cursor (MySQLdb.cursors.DictCursor) 
    sql_select = 'select http from zproxies where update_time is null order by rand() limit 10' 
    local_cursor.execute(sql_select) 
    records = local_cursor.fetchall() 
    id_list = [f['http'] for f in records] 
    print id_list 
def worker(): 
    x=0 
    while x< 5: 
     x = x+1 
     write_good_proxies() 

threads = [] 


for i in range(5): 
    print i 
    t = threading.Thread(target=worker) 
    threads.append(t) 
    t.start() 
Problemi correlati