2015-01-12 3 views
6

У меня есть основной скрипт Python, который подключается к базе данных MySQL и извлекает из него несколько записей. На основе возвращаемого результата начинается столько потоков (экземпляров класса), сколько захвачено множество записей. Каждый поток должен вернуться к базе данных и обновить другую таблицу, установив один флаг состояния в другое состояние («процесс запущен»).Как обрабатывать соединения MySQL с многопоточным Python

Для достижения этой цели я попытался:

1.) Пропустите подключение к базе всех потокам 2.) Открыть новое соединение с базой данных из каждого потока

, но ни один из них не работал.

Я мог запустить свое обновление без каких-либо проблем в обоих случаях с помощью try/except, но таблица MySQL не была обновлена, и ошибка не была сгенерирована. В обоих случаях я использовал фиксацию.

Вопрос в том, как обрабатывать соединения MySQL в таком случае?

Обновление на основе первых нескольких комментариев:

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

трудно сказать что-либо, не зная, как вы подключаетесь к вашей БД и как можно реализовать обновления. – Ashalynd

+0

Я не совсем понимаю ваш вопрос. Является ли самый простой случай работой, например, одним потоком python, подключаться к mysql и обновлять таблицу? – qqibrow

+0

@Ashalynd Спасибо, что нашли время! И извините, но я был АФК. Я обновил свой вопрос с помощью snipet кода из моих основных и кодов классов. Именно так я запускаю экземпляры и открываю соединения с базами данных. Я пытался поймать ошибку при открытии соединения и выполнении запроса из экземпляра с помощью try/except без везения. – g0m3z

ответ

3

Возможно, у меня нет проблем с моим кодом, но с моей версией MySQL. Я использую стандартную версию сообщества MySQL и на основании официальной документации, найденной here:

Плагин пула потоков является коммерческой функцией. Он не включен в дистрибутивы сообщества MySQL.

Я собираюсь перейти на MariaDB, чтобы решить эту проблему.

9

Вот пример использования многопоточности сделки MySQL в Python, я не знаю, таблицу и данные, поэтому, просто изменить код может 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

Извините за мой последний ответ. Ссылаясь на ваш пример выше, у меня есть мой класс и мой основной скрипт в двух разных файлах. Думаю, это не проблема. Другое дело, что я делаю иначе: я не передаю свой data_list в мой поток, потому что мне нужен мой поток для запроса данных из моей базы данных на лету. Итак, что я делаю: 1.) Откройте соединение с базой данных (основной скрипт) 2.) Записи запросов (основной скрипт) 3.) Инициируйте столько экземпляров класса, сколько у меня есть (основной скрипт) 4.) Попробуйте обновить запись таблицы в БД из каждого экземпляра (экземпляр класса) – g0m3z

1

Похоже, что mysql 5.7 поддерживает многопоточность.

Как вы пробовали ранее - абсолютно обязательно пропустите соединение в def def(). определение связей во всем мире была моя ошибка

Вот пример кода, который печатает 10 записей через 5 нитей, в 5 раз

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() 
Смежные вопросы