Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python csv writer : "Unknown Dialect" Error

Tags:

python

csv

writer

I have a very large string in the CSV format that will be written to a CSV file.

I try to write it to CSV using the simplest if the python script

            results=""" "2013-12-03 23:59:52","/core/log","79.223.39.000","logging-4.0",iPad,Unknown,"1.0.1.59-266060",NA,NA,NA,NA,3,"1385593191.865",true,ERROR,"app_error","iPad/Unknown/webkit/537.51.1",NA,"Does+not",false
        "2013-12-03 23:58:41","/core/log","217.7.59.000","logging-4.0",Win32,Unknown,"1.0.1.59-266060",NA,NA,NA,NA,4,"1385593120.68",true,ERROR,"app_error","Win32/Unknown/msie/9.0",NA,"Does+not,false 
"2013-12-03 23:58:19","/core/client_log","79.240.195.000","logging-4.0",Win32,"5.1","1.0.1.59-266060",NA,NA,NA,NA,6,"1385593099.001",true,ERROR,"app_error","Win32/5.1/mozilla/25.0",NA,"Could+not:+{"url":"/all.json?status=ongoing,scheduled,conflict","code":0,"data":"","success":false,"error":true,"cached":false,"jqXhr":{"readyState":0,"responseText":"","status":0,"statusText":"error"}}",false"""
            resultArray = results.split('\n')
            with open(csvfile, 'wb') as f:
                writer = csv.writer(f)
                for row in resultArray:
                writer.writerows(row)

The code returns

"Unknown Dialect"

Error

Is the error because of the script or is it due to the string that is being written?

EDIT

If the problem is bad input how do I sanitize it so that it can be used by the csv.writer() method?

like image 205
SpikETidE Avatar asked Dec 04 '13 07:12

SpikETidE


2 Answers

You need to specify the format of your string:

with open(csvfile, 'wb') as f:
    writer = csv.writer(f, delimiter=',', quotechar="'", quoting=csv.QUOTE_ALL)

You might also want to re-visit your writing loop; the way you have it written you will get one column in your file, and each row will be one character from the results string.

To really exploit the module, try this:

import csv

lines = ["'A','bunch+of','multiline','CSV,LIKE,STRING'"]

reader = csv.reader(lines, quotechar="'")

with open('out.csv', 'wb') as f:
   writer = csv.writer(f)
   writer.writerows(list(reader))

out.csv will have:

A,bunch+of,multiline,"CSV,LIKE,STRING"

If you want to quote all the column values, then add quoting=csv.QUOTE_ALL to the writer object; then you file will have:

"A","bunch+of","multiline","CSV,LIKE,STRING"

To change the quotes to ', add quotechar="'" to the writer object.

like image 103
Burhan Khalid Avatar answered Sep 18 '22 07:09

Burhan Khalid


The above code does not give csv.writer.writerows input that it expects. Specifically:

resultArray = results.split('\n')

This creates a list of strings. Then, you pass each string to your writer and tell it to writerows with it:

for row in resultArray:
    writer.writerows(row)

But writerows does not expect a single string. From the docs:

csvwriter.writerows(rows)

Write all the rows parameters (a list of row objects as described above) to the writer’s file object, formatted according to the current dialect.

So you're passing a string to a method that expects its argument to be a list of row objects, where a row object is itself expected to be a sequence of strings or numbers:

A row must be a sequence of strings or numbers for Writer objects

Are you sure your listed example code accurately reflects your attempt? While it certainly won't work, I would expect the exception produced to be different.

For a possible fix - if all you are trying to do is to write a big string to a file, you don't need the csv library at all. You can just write the string directly. Even splitting on newlines is unnecessary unless you need to do something like replacing Unix-style linefeeds with DOS-style linefeeds.

If you need to use the csv module after all, you need to give your writer something it understands - in this example, that would be something like writer.writerow(['A','bunch+of','multiline','CSV,LIKE,STRING']). Note that that's a true Python list of strings. If you need to turn your raw string "'A','bunch+of','multiline','CSV,LIKE,STRING'" into such a list, I think you'll find the csv library useful as a reader - no need to reinvent the wheel to handle the quoted commas in the substring 'CSV,LIKE,STRING'. And in that case you would need to care about your dialect.

like image 42
Peter DeGlopper Avatar answered Sep 22 '22 07:09

Peter DeGlopper