Python代码没有按顺序执行? MySQLdb UPDATE以意外顺序提交

时间:2015-06-14 22:03:33

标签: python python-2.7 threadpool mysql-python

我正在使用的Python 2.7脚本从MySQL表中检索行,循环处理数据,然后按顺序执行以下操作:

  1. 更新我们之前获得的表行以设置锁定值 在每一行中为TRUE

  2. UPDATE查询执行并通过MySQLdb提交后,一个进程的ThreadPool应该对原始循环的数据运行。

  3. 实际发生的是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()
    

1 个答案:

答案 0 :(得分:1)

即使finally子句引发异常,也保证执行try子句。这里可能发生的是正在引发异常,阻止提交更新,但无论如何都会触发线程。

这并不适合使用try / finally。相反,使用普通的try / except来捕获和记录任何异常,然后可能只有在没有引发异常的情况下才使用else子句来启动线程。