【问题标题】:Write a CSV file asynchronously in Python在 Python 中异步编写 CSV 文件
【发布时间】: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 中,以便异步代码可以很好地与之交互

标签: python csv async-await python-asyncio fastapi


【解决方案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)
                
          
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-29
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 2010-12-13
      • 2019-04-07
      相关资源
      最近更新 更多