Write a CSV file asynchronously in Python

Viewed 5551

I am writing a CSV file with the following function:

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

However, as there is no await allowed over writerows method, there are no rows being written into the CSV file.
How to resolve this issue? Is there any workaround available?
Thank you.
Entire code can be found here.

3 Answers

In my opinion it’s better not to try to use the aiofiles with the csv module and run the synchronous code using loop.run_in_executor and wait it asynchronously like below:

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)

You can use aiocsv. Here is a quick example of writing a row to a CSV file asynchronously:

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())

For more examples follow: https://pypi.org/project/aiocsv/

You can use aiofiles, you just gotta convert the dict to a row :)

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)
            
      
Related