繁体   English   中英

如何继续迭代而不必等待输出完成?

[英]How do I continue iterating without having to wait output to finish?

import sqlite3
conn = sqlite3.connect('output.db')

count = 0
items = []
for item in InfStream: # assume I have an infinite stream
    items.append((item,))
    count += 1
    if count == 10000:
        conn.executemany("INSERT INTO table VALUES (?)", items)
        conn.commit()
        items = []

在此Python代码中,我有一个来自API的长度未知的流,称为InfStream,我想将流中的项目插入到sqlite数据库的表中。 在这种情况下,我首先创建一个包含10,000个项目的列表,然后使用executemany将其插入数据库。 这大约需要1个小时。 但是,代码有问题,当executemany运行时,我必须等待约15秒才能完成。 在我的情况下,这是不可接受的,因为我需要继续从流中获取该项目,否则,如果我延迟太长时间,它将被断开。

我希望在同时运行executemany的同时继续循环。 有可能这样做吗?

nb。 输入比写入慢得多。 输入10,000个项目大约需要1个小时,而输出仅需15秒。

这是一个经典的生产者-消费者问题 ,最好使用Queue处理。

在这种情况下,生产者是您的InfStream,而消费者是您的for块中的所有内容。

将您的顺序代码转换为多线程生产者-消费者模型并使用Queue在线程之间分配数据将是很直接的

考虑你的代码

import sqlite3
conn = sqlite3.connect('output.db')

count = 0
items = []
for item in InfStream: # assume I have an infinite stream
    items.append((item,))
    count += 1
    if count == 10000:
        conn.executemany("INSERT INTO table VALUES (?)", items)
        conn.commit()
        items = []

创建一个Consumer函数 ,以使用数据

def consumer(q):
    def helper():
        while True:
            items = [(q.get(),) for _ in range(10000)]
            conn.executemany("INSERT INTO table VALUES (?)", items)
            conn.commit()
    return helper

生产者功能来生产它,直到无限

def producer():
    q = Queue()
    t = Thread(target=consumer(q))
    t.daemon = True
    t.start()
    for item in InfStream:
        q.put(item)
    q.task_done()

针对注释的补充说明

  1. 从理论上讲,队列可以扩展到无限大小,受系统资源的限制。
  2. 如果消费者不能跟上生产者的步伐

    Span Multiple Consumer将数据放入速度更快的IO设备中,然后将其刷新到数据库中。 使计数可配置和动态。

听起来好像executemany在IO上被阻止了,所以threading在这里实际上可能会有所帮助,所以我会先尝试一下。 特别是,创建一个单独的线程,该线程将简单地对第一个线程扔到共享队列上的数据调用executemany 然后,第一次读取可以继续读取,而第二个线程执行executemany 正如另一个答案所指出的,这是一个生产者-消费者问题。

如果那不能解决问题,请切换到multiprocessing

请注意,如果输入的流入速度比在第二个线程或进程中写入的速度快,那么这两种解决方案都不会起作用,因为填满内存的速度要快于清空内存的速度。 在这种情况下,无论如何,您都必须限制输入的读取率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM