如何使用多线程(或多进程?)来更快地上传数据?

时间:2019-01-22 08:01:47

标签: python-3.x multithreading multiprocessing jira-rest-api python-jira

我有一个问题列表(jira问题):

listOfKeys = [id1,id2,id3,id4,id5...id30000]

我想获取此问题的工作日志,为此,我使用了jira-python库和以下代码:

listOfWorklogs=pd.DataFrame()                 (I used pandas (pd) lib)
lst={}                                       #dictionary for help, where the worklogs will be stored
for i in range(len(listOfKeys)):
    worklogs=jira.worklogs(listOfKeys[i])    #getting list of worklogs
    if(len(worklogs)) == 0:
        i+=1
    else:
        for j in range(len(worklogs)):
            lst = {
                    'self': worklogs[j].self,  
                    'author': worklogs[j].author,
                    'started': worklogs[j].started,
                    'created': worklogs[j].created,
                    'updated': worklogs[j].updated,
                    'timespent': worklogs[j].timeSpentSeconds
                }
            listOfWorklogs = listOfWorklogs.append(lst, ignore_index=True)
########### Below there is the recording to the .xlsx file ################

所以我只是简单地进入每个问题的工作日志,这等效于引用链接: https://jira.mycompany.com/rest/api/2/issue/issueid/worklogs并从此链接中检索信息

问题是这样的问题超过30,000。 并且循环太慢(1个问题大约需要3秒) 我可以以某种方式并行启动多个循环/进程/线程以加快获取工作日志的过程(也许没有jira-python库)吗?

3 个答案:

答案 0 :(得分:0)

我回收了一部分代码,将其制成您的代码,希望对您有所帮助:

from multiprocessing import Manager, Process, cpu_count

def insert_into_list(worklog, queue):
    lst = {
        'self': worklog.self,  
        'author': worklog.author,
        'started': worklog.started,
        'created': worklog.created,
        'updated': worklog.updated,
        'timespent': worklog.timeSpentSeconds
    }
    queue.put(lst)
    return

# Number of cpus in the pc
num_cpus = cpu_count()
index = 0

# Manager and queue to hold the results
manager = Manager()

# The queue has controlled insertion, so processes don't step on each other
queue = manager.Queue()

listOfWorklogs=pd.DataFrame()
lst={}                                       
for i in range(len(listOfKeys)):
    worklogs=jira.worklogs(listOfKeys[i])    #getting list of worklogs
if(len(worklogs)) == 0:
    i+=1
else:

    # This loop replaces your "for j in range(len(worklogs))" loop
    while index < len(worklogs):
        processes = []
        elements = min(num_cpus, len(worklogs) - index)

        # Create a process for each cpu
        for i in range(elements):
            process = Process(target=insert_into_list, args=(worklogs[i+index], queue))
            processes.append(process)

        # Run the processes
        for i in range(elements):
            processes[i].start()

        # Wait for them to finish
        for i in range(elements):
            processes[i].join(timeout=10)

        index += num_cpus

    # Dump the queue into the dataframe
    while queue.qsize() != 0:
        listOfWorklogs.append(q.get(), ignore_index=True)

这应该可以工作,并将时间减少到比计算机中CPU数量少一点。您可以尝试手动更改该数字以获得更好的性能。无论如何,每次操作大约要花费3秒,这让我感到很奇怪。

PS:我无法尝试代码,因为我没有示例,它可能存在一些错误

答案 1 :(得分:0)

我有一些麻烦((

1)在代码中缩进出现第一个“ for”循环和第一个“ if”指令的位置(此指令以及下面的所有内容都应包含在循环中,对吧?)

for i in range(len(listOfKeys)-99):
    worklogs=jira.worklogs(listOfKeys[i])    #getting list of worklogs
    if(len(worklogs)) == 0:
    ....

2)cmd,conda提示符和Spyder不允许您的代码工作是由于以下原因: Python多重处理错误:AttributeError:模块'__ main__'没有属性' spec ' 在google上进行研究之后,我不得不在代码中设置更高的代码: spec = None(但我不确定这是否正确),并且该错误消失了。 顺便说一句,Jupyter Notebook中的代码可以正常工作而不会出现此错误,但是listOfWorklogs为空,这是不对的。

3)当我更正缩进并设置__spec __ = None时,在该位置发生了新的错误: 进程[i] .start() 像这样的错误: “ PicklingError:无法腌制:jira.resources上的属性查找PropertyHolder失败”

如果我从start和join方法中删除括号,该代码将起作用,但是listOfWorklogs((((

我再次请求您的帮助!)

答案 2 :(得分:0)

不从技术角度而是从逻辑角度考虑它呢?您知道您的代码有效,但是每1个问题需要3秒的速度,这意味着需要25个小时才能完成。如果您能够拆分传递到脚本中的Jira问题数量(可能使用日期或发布密钥等),则可以使用基本相同的代码创建多个不同的.py文件,您只需传递每个吉拉门票的其他列表。因此,您可以同时运行其中的4个,这样您就可以将时间减少到每个6.25小时。