I have a list of dictionaries. I need to make a csv-file from this and put it in a zip-archive. I do this:

csv_file = StringIO() csv_writer = csv.writer(csv_file, delimiter=';') csv_writer.writerow([key for key, value in data[0].items()]) for row in data: row_list = [item.encode('cp1251') if isinstance(item, str) else item for item in row] csv_writer.writerow(row_list) zip_file = StringIO() zip_obj = ZipFile(zip_file, 'w', ZIP_DEFLATED) zip_obj.writestr('export.csv', csv_file.getvalue()) zip_obj.close() 

An error occurs:

 TypeError: string argument expected, got 'bytes' 

Tell me, is this solution optimal and how to get rid of this error?

Full Traceback :

 Traceback (most recent call last): File "/home/samojlov/myprojects/monitoring_gpr/venv/lib/python3.5/site-packages/flask/app.py", line 1988, in wsgi_app response = self.full_dispatch_request() File "/home/samojlov/myprojects/monitoring_gpr/venv/lib/python3.5/site-packages/flask/app.py", line 1641, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/samojlov/myprojects/monitoring_gpr/venv/lib/python3.5/site-packages/flask/app.py", line 1544, in handle_user_exception reraise(exc_type, exc_value, tb) File "/home/samojlov/myprojects/monitoring_gpr/venv/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise raise value File "/home/samojlov/myprojects/monitoring_gpr/venv/lib/python3.5/site-packages/flask/app.py", line 1639, in full_dispatch_request rv = self.dispatch_request() File "/home/samojlov/myprojects/monitoring_gpr/venv/lib/python3.5/site-packages/flask/app.py", line 1625, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/home/samojlov/myprojects/monitoring_gpr/app/views/monitoring.py", line 50, in export return export_handler.update(request) File "/home/samojlov/myprojects/monitoring_gpr/app/handlers/data_export_handler.py", line 31, in update zip_obj.writestr('export.csv', csv_file.getvalue()) File "/usr/lib/python3.5/zipfile.py", line 1581, in writestr self.fp.write(zinfo.FileHeader(zip64)) TypeError: string argument expected, got 'bytes' 
  • In Python 3, write the lines, not the bytes in csv (you want: abc , not b'abc' to get) Give a full traceback so that it is clear which code throws an error¶ The word "optimally" requires specifying specific criteria because With the exception of trivial cases, the optimal thing in one situation can be harmful in another¶ If the files are so large that you have to compress, you can use the pandas library: df.to_csv('data.csv.xz', index=False, compression='xz') , where df is an analogue of pandas.DataFrame(data) . - jfs
  • Could you show with an example of how my code will look in working condition? - faoxis
  • create a minimal complete example code that demonstrates the error. Start from scratch (if the error can be obtained without using flask, zipfile or csv, then remove the code using them). The minimum reproducible example is jfs

1 answer 1

 import csv from StringIO import StringIO from zipfile import ZipFile from zipfile import ZIP_DEFLATED data = [ {'dict1_key1': 'dict1_val1', 'dict1_key2': 'dict1_val2'}, {'dict2_key1': 'dict2_val1', 'dict2_key2': 'dict2_val2'} ] csv_file = StringIO() csv_writer = csv.writer(csv_file, delimiter=';') csv_writer.writerow([key for key, value in data[0].items()]) for row in data: row_list = [item.encode('cp1251') if isinstance(item, str) else item for item in row] csv_writer.writerow(row_list) zip_obj = ZipFile("archive.zip", 'w', ZIP_DEFLATED) zip_obj.writestr('export.csv', csv_file.getvalue()) zip_obj.close() 

An archive.zip is created with the export.csv file. The content of the export.csv file is thus:

 dict1_key1;dict1_key2 dict1_key1;dict1_key2 dict2_key1;dict2_key2 

Python version 2.7.11.

  • Where are the values ​​in the file? Some keys ... - faoxis
  • Note the following line: 'csv_writer.writerow ([key for key, value in data [0] .items ()])' no one here with value and does not work. Also here: 'item.encode (' cp1251 ') if isinstance (item, str) else item for item in row - Fedir Alifirenko