在下面的代码中,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可以使用它来进行批量插入
答案 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
中的任何内容,例如空字符串,空列表等。但这应该适用于您的用例。