import pymysql import multiprocessing from math import ceil from helpers.general_use import list_chunks from mapper.mapper import process_file from mapper.mapper import consumer from fsixer import fs_fix_up from config import log_fields from helpers.general_use import prep_insert_sql def multiprocess_fs(isrc_list, config, log, file, table_appendix=None): log_table = config['LOG_TABLE'] # Init queues inQ = multiprocessing.SimpleQueue() outQ = multiprocessing.SimpleQueue() # Create workers workers = [multiprocessing.Process( target=consumer, args=(inQ, outQ, fs_fix_up)) for i in range(config['num_threads'])] # Start workers for w in workers: w.start() # Get full length # print("Getting input file length.") full = len(isrc_list) step = int(config['ROW_STEP']) # Get per thread line count thread_boundary = 100000 # ceil(full / config['num_threads']) # How many chunks are being created num_chunks = ceil(len(isrc_list)/thread_boundary) # Use table_appendix if necessary if table_appendix: target_table = config['TARGET_TABLE'] + "_" + str(table_appendix) else: target_table = config['TARGET_TABLE'] # Init parameter list var param_list = [] log.log(25, "Fact_Sales Multiprocessing beginning.") # Generate params for i, chunk in enumerate(list_chunks(isrc_list, thread_boundary)): start = i * thread_boundary stop = ((i + 1) * thread_boundary) - 1 param_list.append( {'start': start, 'stop': stop, 'full': len(isrc_list), 'config': config, 'name': "Fact_Sales: {} of {} (rows {}-{} of {})".format( i, num_chunks, start, stop, full), 'chunk': chunk, 'target_table': target_table, 'file': file }) # Load the Queues process_file(param_list, inQ, outQ) # Tell all workers, no more data (one msg for each) for i in range(config['num_threads']): inQ.put(None) # Join on the workers for w in workers: w.join() adjusted_rows = 0 # Target mysql connection target_conn = pymysql.connect(host=config['TARGET_HOST'], user=config['TARGET_USER'], password=config['TARGET_PASSWORD'], db=config['TARGET_DATABASE'], port=int(config['TARGET_PORT']), charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor) # Target Cursor t_cursor = target_conn.cursor() # Print out final results (i*16) for i, msg in enumerate(param_list): for line_dict in msg[1]: # line_dict = line.toDict() line_dict['reason'] = "Process Error (Fact Sales)" line_dict['filename'] = file line_dict['id'] = None sql, line_dict = prep_insert_sql(line_dict, log_fields, log_table) t_cursor.execute(sql, list(line_dict.values())) # with open('fact_sales_'+target_table +'-process_error.log', "a") as f: # f.writelines(msg[1]) print(i, msg[0], (msg[2] if msg[2] else ""), (str(msg[3] if msg[3] else "0")) + " lines adjusted by fact_sales data") adjusted_rows += int(msg[3] if msg[3] else 0) return adjusted_rows