Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何异步运行数据库请求?_Python_Python 3.x_Python Asyncio_Aiohttp - Fatal编程技术网

Python 如何异步运行数据库请求?

Python 如何异步运行数据库请求?,python,python-3.x,python-asyncio,aiohttp,Python,Python 3.x,Python Asyncio,Aiohttp,当我运行这个程序时,它会用响应代码一个接一个地列出数据库中的网站,运行一个非常小的列表大约需要10秒钟。它应该快得多,而且不会异步运行,但我不知道为什么 import dblogin import aiohttp import asyncio import async_timeout dbconn = dblogin.connect() dbcursor = dbconn.cursor(buffered=True) dbcursor.execute("SELECT thistable FROM

当我运行这个程序时,它会用响应代码一个接一个地列出数据库中的网站,运行一个非常小的列表大约需要10秒钟。它应该快得多,而且不会异步运行,但我不知道为什么

import dblogin
import aiohttp
import asyncio
import async_timeout

dbconn = dblogin.connect()
dbcursor = dbconn.cursor(buffered=True)
dbcursor.execute("SELECT thistable FROM adatabase")
website_list = dbcursor.fetchall()

async def fetch(session, url):
    with async_timeout.timeout(30):
        async with session.get(url, ssl=False) as response:
            await response.read()
            return response.status, url

async def main():
    async with aiohttp.ClientSession() as session:
        for all_urls in website_list:
            url = all_urls[0]
            resp = await fetch(session, url)
            print(resp, url)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

dbcursor.close()
dbconn.close()

解释细节。您需要做的是在
Future
对象中传递每个fetch调用,然后根据需要将这些调用的列表传递给
asyncio.wait
asyncio.gather

您的代码如下所示:

async def fetch(session, url):
    with async_timeout.timeout(30):
        async with session.get(url, ssl=False) as response:
            await response.read()
            return response.status, url

async def main():
    tasks = []
    async with aiohttp.ClientSession() as session:
        for all_urls in website_list:
            url = all_urls[0]
            task = asyncio.create_task(fetch(session, url))
            tasks.append(task)

        responses = await asyncio.gather(*tasks)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    future = asyncio.create_task(main())
    loop.run_until_complete(future)

另外,您确定需要调用
loop.close()
吗?文件提到

调用此函数时,循环不得运行。任何挂起的回调都将被丢弃

此方法清除所有队列并关闭执行器,但不等待执行器完成



正如@user4815162342发布的和链接中提到的,当我们知道参数是一个协程时,最好使用
create\u task
方法,而不是
sure\u future
方法。请注意,这是在Python 3.7中添加的,所以以前的版本应该继续使用<代码> EnSurryEnguty。

请在您知道参数是一个协同程序时考虑。code>Survey_future是一个专门的函数,设计用于组合器,如
gather
将任意可等待项转换为期货。谢谢你的提示,我不知道这一点。我将编辑我的帖子。谢谢!那篇文章真的很有帮助,我能让它在很大程度上发挥作用。它只是需要一点调整,让它做我想要的。