0

Looking to edit rows in my csv document and I keep getting flip-flopping issues between requiring "bytes-like object is required" and "Error: iterator should return strings, not bytes"

Running Python3

I have tried changing the mode from "rb" to "r" as well as placing generic string texts in the writer.writerow loop.

The CSV file is definitely comma separated, not tab separated.

I am following this youtube tutorial: https://www.youtube.com/watch?v=pOJ1KNTlpzE&t=75s (1:40)

temp_file = NamedTemporaryFile(delete=False)


with open('clientlist.csv','rb') as csvfile, temp_file:
    reader = csv.DictReader(csvfile)
    fieldnames = ['Account Name','Account Number','Date Last Checked']
    writer = csv.DictWriter(temp_file, fieldnames=fieldnames)
    writer.writeheader()
    print(temp_file.name)
    for row in reader:
        writer.writerow({
                'Account Name': row['Account Name'],
                'Account Number': row['Account Number'],
                'Date Last Checked': row['Date Last Checked'],
            })

#shutil.move(temp_file.name, client_list)

Expected result should make it when I open the temp_file there is data. Then, from what I read, the shuthil should copy it. Right now the temp_file is blank.

Any ideas if it would be easier to start from scratch and use numpy or pandas? Saw this video on that: https://www.youtube.com/watch?v=pbjGo3oj0PM&list=PLulVrUACBIGX8JT7vpoHVQLYqgOKeunb6&index=16&t=0s

  • https://stackoverflow.com/questions/4739066/python-3-1-3-win-7-csv-writerow-error-must-be-bytes-or-buffer-not-str – BCJuan Apr 04 '19 at 13:08

2 Answers2

2

According to the NamedTemporaryFile documentation, named temporary files are opened in w+b mode by default - i.e. binary.

Since you are reading and writing csv files, it makes no sense (to me) to operate in binary mode, so rather open the input file in r mode, and ask for a temporary file in w mode:

import csv
import tempfile

temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False) # note the mode argument

with open('clientlist.csv','r') as csvfile, temp_file:  #note the mode argument
    reader = csv.DictReader(csvfile)
    fieldnames = ['Account Name','Account Number','Date Last Checked']
    writer = csv.DictWriter(temp_file, fieldnames=fieldnames)
    writer.writeheader()
    for row in reader:
        writer.writerow({
            'Account Name': row['Account Name'],
            'Account Number': row['Account Number'],
            'Date Last Checked': row['Date Last Checked'],
        })

That seems to behave for me.

andrew-g-za
  • 967
  • 8
  • 13
  • I had to modify your temp_file var but that worked! `temp_file = NamedTemporaryFile(mode='w', delete=False) # note the mode argument`, I believe that was because I used `from tempfile import NamedTemporaryFile` – Garrett Mark Scott Apr 05 '19 at 12:57
0

Here they recommend defining the encoding:

Python 3.1.3 Win 7: csv writerow Error "must be bytes or buffer, not str"

Nevertheless, why don't you open the temporary file with open?

Like,

temp_file = open("new_file.csv", 'wb');
BCJuan
  • 805
  • 8
  • 17
  • 1
    The `with` statement ensures they don't need to remember to close the file after they've opened it, which is something they'd have to do if they used only `open`. The way OP is opening the file is fine. – m13op22 Apr 04 '19 at 13:28