Creating and writing a CSV file

I would like to write some extracted data to a CSV file on the host machine.

I am trying a very simple case:

os.startfile(“output.csv”)
file = script.dump_csv(csv_rows, “output.csv”)

And IP throws the error:

IronPython Traceback:
Traceback (most recent call last):
File “C:\Users\pauldavis\Documents\Revit\Nedra.extension\Nedra.tab\Export.panel\E2.pushbutton\e3_script.py”, line 23, in
WindowsError: [Errno 2] [Errno 2] The system cannot find the file specified

Eventually I will want to create a new file each run with the doc name and timestamp, but for now I am trying to crawl before I walk :slight_smile:.

I may be mixing two methods here, so I would love a quick hint about this operation.

I am open to using more native Python file handling functions, if that’s easier/idiomatic.

Thanks!

Paul

I have also created a file at that path, but get the same result.

Here is a snippet I worked on yesterday:

from os import path, mkdir
import csv

# Export folder
export_folder = path.join("C:\\", "export")
# or 
# export_folder = path.dirname(path.abspath(__file__)) #CURRENT_FOLDER

# create directory if it doesn't exist
if not path.exists(export_folder):
mkdir(export_folder)

# Export file name
export_file_name = "data.csv"
# Export file path
export_file_path = path.join(export_folder, export_file_name)

# Export file header
columns = ["user", "date"]
# data
user = ['john', 'jane', 'joe']
date = ['2018-01-01', '2018-01-02', '2018-01-03']
data = [user, date]

# create new csv file at export_file_path
with open(export_file_path, mode='wb') as csv_file: # wb = write binary or ab = append binary if you want to kep the existing data
    writer = csv.writer(csv_file, lineterminator='\n')
    writer.writerow(columns)
    for data in zip(user, date):
        writer.writerow(data)

The dump_csv() does pretty much the same stuff as above except it overwrites the file every time it runs thanks to the wb mode set

Thanks - this is a super step ahead.

For me, that gives a CSV file with the content:

user,date
IronPython.Runtime.List,IronPython.Runtime.List

Dunno why user and date get replace by their types…

This code does a better CSV job for me, with the same setup:

> with open(export_file_path, mode='w') as csv_file:
> writer = csv.writer(csv_file, lineterminator='\n')
>     writer.writerow(columns)
>     for data in zip(user, date):
>         writer.writerow(data)  # write each tuple as a row

You are right, I had not tested it. And I was missing the indentation.
I fixed my code above for the sake of completeness

Hello Paul,

I´m using a while loop for reading and writing csv files.

As an attempt could fail and raise an OSError it is safer to allow several retries to make sure the reading and writing will be successful even if the file will not respond at the first try.

Without the while loop i had a failing of about 5% at accessing the file. With the while loop this now worked thousands of times without any problem.
Just to keep that in mind if you ever encounter such a problem.

You can find more information and explanation on why and how I wrote this code here:

def Read_LOG():
    retry = 0
    max_retries=5
    while True:
        try:
            with io.open(LogFilePath,"r", encoding = "utf-8") as LOGfile:
				LOG = LOGfile.read().splitlines()
        except OSError:
            time.sleep(0.5)
            retry += 1
            if retry > max_retries:
                raise
        else:
            return LOG
		
def Write_LOG():
	LOG = Read_LOG()
	LOG_New_Entry = LOG_Entry()
	LOG.append(LOG_New_Entry)
	retry = 0
	max_retries=5
	while True:
		try:
			with io.open(LogFilePath,"w", encoding = "UTF8", newline='') as LOGfile:	
				for L in LOG:
					writer = csv.writer(LOGfile,delimiter="'")
					writer.writerow([L])
		except OSError:
			time.sleep(0.5)
			retry += 1
			if retry > max_retries:
				raise
		else:
			return LOG_New_Entry

PS: In my final version i now check if the file exists before writing:

def Write_LOG():
	if exists(LogFilePath):
		...
2 Likes