Basically, I need final a csv file, whose contents look like Header, and then the data: (Boto3 upload_file does the job of writing temporary file, into csv)
Expectation:
Name,Code
Adam,12
I am able to get this, by using:
with tempfile.NamedTemporaryFile(mode="a t", suffix =".csv", delete=True) as fileName:
for data in allData:
fileName.write(data)
fileName.flush()
Additional doubt: without this flush(), all of the data do not come in the final csv. flush() clears the buffer memory, I presume. So, is there a way to check, if the memory is getting full, and the remaining data are left out?
But, when I am using csv.writer:
writer = csv.write(fileName)
with tempfile.NamedTemporaryFile(mode="a t", suffix =".csv", delete=True) as fileName:
for data in allData:
writer.writerow(data)
Reality:
N,a,m,e","C,o,d,e
A,d,a,m","1,2"
Using Python 3.8
A data looks like: Adam,12
Need help writing this with csv writer. I have seen references of StringIO being used to fix similar cases, but do not know how to implement. Is there a way out?
CodePudding user response:
This doesn't have anything to do with the temporary directory.
Here is part of the introduction about CSV writer objects (bold added):
A row must be an iterable of strings or numbers for Writer objects and a dictionary mapping fieldnames to strings or numbers... for DictWriter objects
But you are passing in a single string: "Adam,12"
. So what's going on?
Strings themselves are iterables over the characters in the string:
>>> for character in "Adam":
... print(character)
...
A
d
a
m
And since Python doesn't have a distinct character class, each of those single-character values is also a string. So strings are iterables of strings.
When you give an iterable of strings to csvwriter.writerow()
, it writes each string in the iterable to its own column. In this case, that means one-character strings taken from the input.
To get the behaviour you're after, you'll need to pass something like ["Adam", 12]
(not "Adam,12"
) to the CSV writer. I'm not sure where your inputs are coming from, so there might be a better way to do this, but you could split your strings on the comma as you pass them in:
for data in allData:
writer.writerow(data.split(","))
This works because "Adam,12".split(",")
returns ["Adam", "12"]
. Note that this won't work properly if your inputs have multiple commas.