控制生成的进程返回的值

时间:2014-05-08 09:34:09

标签: python sqlalchemy multiprocessing

在下面的代码中,worker函数检查传递的数据是否有效以及它是否有效,它返回一个将在批量SQLAlchemy Core插入中使用的字典。如果它无效,我希望不将None值添加到receiving_list,因为如果是,则批量插入将失败,因为单个None值无法映射到表结构

from datetime import datetime
from sqlalchemy import Table
import multiprocessing

CONN = Engine.connect() #Engine is imported from another module
NUM_CONSUMERS = multiprocessing.cpu_count() 
p = multiprocessing.Pool(NUM_CONSUMERS)

def process_data(data):
    #Long process to validate data
    if is_valid_data(data) == True:
        returned_dict = {}
        returned_dict['created_at'] = datetime.now()
        returned_dict['col1'] = data[0]
        returned_dict['colN'] = data[N]
        return returned_dict
    else:
        return None


def spawn_some_processes(data):
    table_to_insert = Table('postgresql_database_table', meta, autoload=True, autoload_with=Engine)
    While True:
        #Get some data here and pass it on to the worker
        receiving_list = p.map(process_data, data_to_process)

    try:
        if len(receiving_list) > 0:
            trans = CONN.begin()
            CONN.execute(table_to_insert.insert(), receiving_list)
            trans.commit()
    except IntegrityError:
        trans.rollback()
    except:
        trans.rollback()

尝试重新解释这个问题,当衍生进程返回值receiving_list时,如何阻止衍生进程添加到None

解决方法是将queue.put()queue.get()的队列合并到put仅有效数据。这样做的缺点是,在进程结束后,我必须unpack队列,这增加了开销。我理想的解决方案是返回一个干净的字典列表,SQLAlchemy可以使用它来进行批量插入

1 个答案:

答案 0 :(得分:0)

您只需从列表中删除None条目:

received_list = filter(None, p.map(process_data, data_to_process))

即使对于非常庞大的列表,这也很快:

>>> timeit.timeit('l = filter(None, l)', 'l = range(0,10000000)', number=1)
0.47683095932006836

请注意,使用过滤器会删除bool(val) is False中的任何内容,例如空字符串,空列表等。但这应该适用于您的用例。