0

I have written a function that turns a queryset into a CSV file, that is then emailed to the user. Since there is no need to store the file on the system I've decided to use Tempfile objects. However though I am succesfull in writing to these objects, I am unable to read them - which is preventing me from emailing them as attachment

columns = instances[0].get_columns
# create tempfile, in TEXT (t) mode so as not to trip up the
# csv module, which cant handle binary data.
file = tempfile.NamedTemporaryFile(mode='wt')

try:
    writer = csv.writer(file)
    writer.writerow([field[0] for field in columns])

    for instance in instances:
        row = [getattr(instance, str(field[0])) for field in columns]


    # email the file
    body = 'The exported file has been included as a attachment.'
    email = EmailMessage(
    subject='CSV Export',
    from_email='******',
    to=['*****'],
    body=body,
    )
    email.attach('export.csv', file, 'text/csv')
    email.send()

This triggers the following error: '_io.TextIOWrapper' object has no attribute 'splitlines'

After some googling it seemed that I had to .read() the file however, the new code (email.attach('export.csv', file.read(), 'text/csv')UnsuportedOperation: not readable` error.

Other posts suggest that, besides .read() I needed to 'rewind' the file using file.seek(0, os.SEEK_END), but the not readable error keeps triggering.

If I remove the file.read() but keep the file.seek(0, os.SEEK_END) which leads to a return of the '_io.TextIOWrapper' object has no attribute 'splitlines' error.

Does anyone know what I am doing wrong?

Jasper
  • 2,131
  • 6
  • 29
  • 61
  • File is not readable perhaps because you opened the file in write mode. Change the mode and then maybe it would work. – Kishu Agarwal Mar 04 '18 at 13:34
  • Thanks for your response! I tried changing it to file = tempfile.NamedTemporaryFile(mode='r+t'), but unfortunately the problem persists. – Jasper Mar 04 '18 at 13:46
  • I don't know what is the current state of your code is, but you would have to have the correct mode ('r+t') is fine. Then after writing the file, you would have to seek the file to the first character by file.seek(0). Then while attaching the file, instead of passing file, pass file.read(). – Kishu Agarwal Mar 04 '18 at 14:26
  • The 'file.seek(0, os.SEEK_END)' was using was tripping the code up. I replaced it with the 'file.seek(0)' you suggested and it worked! Many thanks! – Jasper Mar 04 '18 at 15:11

0 Answers0