我正在使用的Python 2.7脚本从MySQL表中检索行,循环处理数据,然后按顺序执行以下操作:
更新我们之前获得的表行以设置锁定值 在每一行中为TRUE
在 UPDATE查询执行并通过MySQLdb提交后,一个进程的ThreadPool应该对原始循环的数据运行。
实际发生的是UPDATE查询似乎在ThreadPool完成后以某种方式提交。我尝试将它重构为try / finally语句以确保,但现在它仍然会在之后执行,或者只是不提交UPDATE并且仍然运行ThreadPool。
当然,这是一个令人头疼的问题。我认为我只是在做一些非常错误而且显而易见的事情但是在看了这么久之后却没有抓住它。非常感谢任何输入!
这是要点:
from multiprocessing.pool import ThreadPool, IMapIterator
import MySQLdb as mdb
import os, sys, time
import re
from boto.s3.connection import S3Connection
from boto.s3.bucket import Bucket
...
con = mdb.connect('localhost', 'user', 'pass', 'db')
with con:
cur = con.cursor()
cur.execute("SELECT preview_queue.filename, preview_queue.product_id, preview_queue.track, products.name, preview_queue.id FROM preview_queue join `catalog_module-products` AS products on products.id = preview_queue.product_id where locked != 1")
rows = cur.fetchall()
mp3s_to_download = []
lock_ids = []
last_directory = ""
if len(rows) > 0:
for row in rows:
base_dir = str(get_base_dir(row[1], row[3]))
mp3s_to_download.append([base_dir, str(row[0])])
if last_directory != "preview_temp/"+base_dir:
if not os.path.exists("preview_temp/"+base_dir):
try:
os.makedirs("preview_temp/"+base_dir)
except OSError, e:
pass
last_directory = "preview_temp/"+base_dir
lock_ids.append(str(row[4]))
if len(lock_ids) > 0:
action_ids = ','.join(lock_ids)
try:
cur.execute("UPDATE preview_queue SET locked = 1 WHERE id IN ({})".format(action_ids))
con.commit()
finally:
pool = ThreadPool(processes=20)
pool.map(download_file, mp3s_to_download)
cur.close()
答案 0 :(得分:1)
即使finally
子句引发异常,也保证执行try
子句。这里可能发生的是正在引发异常,阻止提交更新,但无论如何都会触发线程。
这并不适合使用try / finally。相反,使用普通的try / except来捕获和记录任何异常,然后可能只有在没有引发异常的情况下才使用else
子句来启动线程。