質問

I am importing a simple CSV file onto my GAE App and want to select the first item of a list. The code below imports a CSV file and saves each line as a list. Now I want it to show only the first entry of each list item, but if I use data[1] it says that this is out of range. I think I'm missing something obvious but can't seem to figure it out. Any help would be very much appreciated!

class CSVImport(webapp2.RequestHandler):
def post(self):
  csv_file = self.request.get('csv_import')
  fileReader = csv.reader(csv_file.split("\n"))
  dataset = []
  dataset.extend(fileReader)
  for data in dataset:
    self.response.out.write(data)

EDIT 1

For information, the initial code gave the following response: ['name', 'description', 'url', 'category', 'deliverycost', 'returning', 'provider', 'prov_id', 'logo', 'last_update']['Amazon', 'Changed the desc', 'http://www.url.com', 'Meta', '5 Euro', 'Gratis', 'Affilinet', 'Test', '/images/logos/amazon.jpg', '2012-12-26 13:11:22.519000']['B Shop', '', 'http://www.url.com', '', '', '', '', '', '', '2012-12-26 13:19:01.545000']['Otto', 'Test something', 'http://amazon.de', 'Meta', '', 'sdgs', 'sdgsdg', 'sdgds', 'dsgdsg', '2012-12-26 13:09:10.716000'][]

Based on RocketDonkey's answer I rewrote the code to the following:

class CSVImport(webapp2.RequestHandler):
def post(self):
   csv_file = self.request.get('csv_import')
   with open(csv_file, 'rb') as f:
      fileReader = csv.reader(f)
      for data in fileReader:
        print data[0]

This however gives the following error: IOError: [Errno 13] file not accessible: 'name,description,url,category,deliverycost,returning,provider,prov_id,logo,last_update\r\nAmazon,Changed the desc,http://www.url.com,Meta,5 Euro,Gratis,Affilinet,Test,/images/logos/amazon.jpg,2012-12-26 13:11:22.519000\r\nB Shop,,http://www.url.com,,,,,,,2012-12-26 13:19:01.545000\r\nOtto,Test something,http://amazon.de,Meta,,sdgs,sdgsdg,sdgds,dsgdsg,2012-12-26 13:09:10.716000\r\n'

The content after 'accessible:' is the exact content of the CSV file, which is why I find the error 'file not accessible' remarkable. The CSV file is coming in through an HTML form which looks as follows:

<form action="/admin/shop/import" method="post" enctype="multipart/form-data">
   <p><strong>Import:</strong>
   <input type="file" name="csv_import" id="csv_import" accept=".csv">
   <input type="submit" value="Import"></p>
</form>

I am aware that the RemoteAPI is probably a better solution for this, however I am having troubles setting this up under Windows 7, which is why I am trying to build this as a work-around for now. So once I am able the select data from a single column of the CSV file, I will match it with a database model which I have defined.

役に立ちましたか?

解決

Edit: Per your updated response, it looks like you are getting the actual file contents in csv_file, and your newline separator is \r\n. Therefore I would suggest trying the following:

In [1]: import csv

In [2]: csv_file = # Copied the response from your error into this variable

In [3]: reader = csv.reader(csv_file.split('\r\n'))

In [4]: for row in reader:
   ...:     if row:
   ...:         print row[0]
   ...:         
   ...:         
name
Amazon
B Shop
Otto

The if row check is done because you can see that the end of the CSV string is \r\n, which means that when you split on the \r\n character, the last item of the list will be empty. When that empty element is read by csv.reader, the result is an empty list, which as you know will fail with an IndexError if you try to do any sort of accessing by index. Alternatively, you could do this beforehand to ensure that all 'rows' contain values:

In [8]: csv_file = [row for row in csv_file.split('\r\n') if row]

In [9]: reader = csv.reader(csv_file)

In [10]: for row in reader:
   ....:     print row[0]
   ....:     
   ....:     
name
Amazon
B Shop
Otto

I'm not sure of your use case, but if you are using your code to upload data to your app, I would suggest taking a look at the Remote API - this provides a very clean way to go about doing that and precludes you from having to use special handlers, etc.

I'll make the assumption that you are passing in an actual CSV (not a string name of a file - if you are passing in a filename see below), so something like this:

some_csv = 'header1,header2\nvalue1,value2'

What you're doing is splitting on the newlines and passing csv.reader an object over which to iterate, the result of which is a csv.reader object. Note that you can iterate directly over this object, so you do not need to create a separate dataset variable:

In [1]: import csv

In [2]: some_csv = 'header1,header2\nvalue1,value2'

In [3]: fileReader = csv.reader(some_csv.split("\n"))

In [4]: fileReader
Out[4]: <_csv.reader object at 0x1306440>

In [5]: for data in fileReader:
   ...:     print data
   ...:     
   ...:     
['header1', 'header2']
['value1', 'value2']

Using print data[1] will print the second item of each list (as mentioned by @sadaf2605, Python uses zero-based indexing, so the first element would actually be data[0]). Your error indicates that there is only one element per row, so the first thing to check would be whether or not you are actually passing comma-separated values into that parameter.

However you also mention that you are importing a CSV file - is your URL parameter a string reference to a filename itself? If so, that will cause an issue because you won't actually be opening the file - you will be iterating over an object that only contains the name of the file itself, not the data:

In [1]: import csv

In [2]: some_csv = 'some_csv.csv'

In [3]: fileReader = csv.reader(some_csv.split("\n"))

In [4]: for data in fileReader:
   ...:     print data
   ...:     
   ...:     
['some_csv.csv']

Again on the zero-based indexing, you can see that there is not a second element to this array, so you will get the IndexError. If this is your case, you can try this (although I would again suggest the Remote API :) )

In [1]: import csv

In [2]: some_csv = 'some_csv.csv'

In [3]: with open(some_csv, 'rb') as f:
   ...:     fileReader = csv.reader(f)
   ...:     for data in fileReader:
   ...:         print data[0]
   ...:         
   ...:         
header1
value1

他のヒント

in python the array starts from 0...n-1, so when you are trying show only the first entry of each list item, then definitely you should use array[0], it should not be data[1] by any way.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top