在 Python 中异步编写 CSV 文件

Posted

技术标签:

【中文标题】在 Python 中异步编写 CSV 文件【英文标题】:Write a CSV file asynchronously in Python 【发布时间】:2020-08-09 08:50:10 【问题描述】:

我正在编写具有以下功能的 CSV 文件:

import csv
import os
import aiofiles


async def write_extract_file(output_filename: str, csv_list: list):
    """
    Write the extracted content into the file
    """
    try:
        async with aiofiles.open(output_filename, "w+") as csv_file:
            writer = csv.DictWriter(csv_file, fieldnames=columns.keys())
            writer.writeheader()
            writer.writerows(csv_list)
    except FileNotFoundError:
        print("Output file not present", output_filename)
        print("Current dir: ", os.getcwd())
        raise FileNotFoundError

但是,由于 writerows 方法不允许等待,因此没有行被写入 CSV 文件。 如何解决这个问题?有什么解决方法吗? 谢谢。 完整代码可以在here找到。

【问题讨论】:

请注意,对本地文件使用异步 io 往往比同步 io 慢。您可能只是使用同步(即非异步)方法并包装在 loop.run_in_executor 中,以便异步代码可以很好地与之交互 【参考方案1】:

在我看来,最好不要尝试将aiofilescsv 模块一起使用,并使用loop.run_in_executor 运行同步代码并像下面这样异步等待它:

def write_extract_file(output_filename: str, csv_list: list):
    """
    Write the extracted content into the file
    """
    try:
        with open(output_filename, "w+") as csv_file:
            writer = csv.DictWriter(csv_file, fieldnames=columns.keys())
            writer.writeheader()
            writer.writerows(csv_list)
    except FileNotFoundError:
        print("Output file not present", output_filename)
        print("Current dir: ", os.getcwd())
        raise FileNotFoundError


async def main():
    loop = asyncio.get_running_loop()
    await loop.run_in_executor(None, write_extract_file, 'test.csv', csv_list)

【讨论】:

请注意,这将同步运行write_extract_file。您需要使用await loop.run_in_executor(None, write_extract_file, 'test.csv', csv_list) 来实际异步运行它 谢谢山姆和亚历克斯。【参考方案2】:

您可以使用aiocsv。下面是一个将行异步写入 CSV 文件的快速示例:

import asyncio
import aiofiles
from aiocsv import AsyncWriter

async def main():
    async with aiofiles.open('your-path.csv', 'w') as f:
        writer = AsyncWriter(f)
        await writer.writerow(['name', 'age'])
        await writer.writerow(['John', 25])

asyncio.run(main())

更多示例请关注:https://pypi.org/project/aiocsv/

【讨论】:

【参考方案3】:

你可以使用 aiofiles,你只需要将 dict 转换为一行 :)

import aiofiles

async def write_extract_file(
    output_filename: str, csv_list: list
):

    cols = columns.keys()

    async with aiofiles.open(output_filename, mode='w+') as f_out:

        await f_out.write(','.join(cols)+'\n')

        for data in csv_list:

            line = []

            for c in cols:
                line.append(str(data[c]) if c in data else '')

            line = ','.join(line) + '\n'
    
            await f_out.write(line)
            
      

【讨论】:

以上是关于在 Python 中异步编写 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章

编写csv文件 - Python [重复]

使用 Python 在 CSV 文件中编写完全相同的内容

在 Python 中编写适用于 Windows 中的 Python 2.7+ 和 Python 3.3+ 的 .CSV 文件

可以在python中编写异步文件吗?

如何将包含 200,00 行的巨大 CSV 文件导入 MySQL(异步且快速)?

在csv python中编写查询行