2010-06-03 24 views
7

के साथ सीएसवी फ़ाइल अपलोड और पार्स करें, मुझे आश्चर्य है कि अगर कोई भी पाइथन और जीई की बेहतर समझ के साथ मेरी मदद कर सकता है। मैं एक फॉर्म से जीएस डेटास्टोर में एक सीएसवी फ़ाइल अपलोड कर रहा हूं।Google ऐप इंजन

class CSVImport(webapp.RequestHandler): 
    def post(self): 
    csv_file = self.request.get('csv_import') 
    fileReader = csv.reader(csv_file) 
    for row in fileReader:  
     self.response.out.write(row) 

मैं एक ही समस्या है कि किसी यहां उल्लेख में चल रहा हूँ - http://groups.google.com/group/google-appengine/browse_thread/thread/bb2d0b1a80ca7ac2/861c8241308b9717

है, csv.reader प्रत्येक चरित्र और नहीं लाइन पर पुनरावृत्ति है। एक Google इंजीनियर ने इस स्पष्टीकरण को छोड़ा:

कॉल self.request.get ('csv') एक स्ट्रिंग देता है। जब आप स्ट्रिंग पर फिर से सक्रिय होते हैं, तो आप पात्रों पर फिर से चलते हैं, रेखाओं पर नहीं।

class ProcessUpload(webapp.RequestHandler): 
    def post(self): 
    self.response.out.write(self.request.get('csv')) 
    file = open(os.path.join(os.path.dirname(__file__), 'sample.csv')) 
    self.response.out.write(file) 

    # Iterating over a file 
    fileReader = csv.reader(file) 
    for row in fileReader: 
     self.response.out.write(row) 

    # Iterating over a string 
    fileReader = csv.reader(self.request.get('csv')) 
    for row in fileReader: 
     self.response.out.write(row) 

मैं वास्तव में स्पष्टीकरण का पालन नहीं करते हैं, और यह लागू करने असफल रहा था: आप अंतर यहाँ देख सकते हैं। क्या कोई इस बारे में स्पष्ट स्पष्टीकरण प्रदान कर सकता है और एक प्रस्तावित फिक्स?

धन्यवाद, अगस्त

उत्तर

13

कम जवाब है, इस प्रयास करें:

fileReader = csv.reader(csv_file.split("\n")) 

लांग जवाब है, निम्नलिखित पर विचार:

for thing in stuff: 
    print thing.strip().split(",") 

अगर सामान एक फ़ाइल सूचक है, प्रत्येक बात एक पंक्ति है। अगर सामान एक सूची है, तो प्रत्येक चीज एक वस्तु है।अगर सामान एक स्ट्रिंग है, तो प्रत्येक चीज एक चरित्र है।

csv.reader द्वारा लौटाई गई वस्तु पर इटरेटिंग आपको उस वस्तु को फिर से शुरू करने के समान व्यवहार करने जा रहा है, केवल प्रत्येक आइटम CSV-parsed के साथ। यदि आप एक स्ट्रिंग पर फिर से सक्रिय करते हैं, तो आपको प्रत्येक वर्ण का एक CSV-parsed संस्करण मिलेगा।

+0

स्पष्टीकरण के लिए धन्यवाद, यह अब मेरे लिए बहुत अधिक समझ में आता है। –

+0

मैं .split ('\ n') के बजाय .splitlines() का उपयोग करने पर विचार करूंगा –

8

मैं क्या गूगल इंजीनियर आप का उल्लेख कहा की तुलना में एक स्पष्ट व्याख्या नहीं सोच सकते हैं। तो चलिए इसे थोड़ा सा तोड़ दें।

पायथन csv मॉड्यूल फ़ाइल जैसी वस्तुओं पर काम करता है, यह एक फ़ाइल या कुछ है जो एक पायथन फ़ाइल की तरह व्यवहार करता है। इसलिए, csv.reader() को फ़ाइल ऑब्जेक्ट प्राप्त करने की अपेक्षा है क्योंकि यह केवल आवश्यक पैरामीटर है।

webapp.RequestHandler अनुरोध ऑब्जेक्ट फॉर्म में पोस्ट किए गए HTTP पैरामीटर तक पहुंच प्रदान करता है। HTTP में, पैरामीटर को कुंजी-मान जोड़े के रूप में पोस्ट किया जाता है, उदाहरण के लिए, csv=record_one,record_two। जब आप self.request.get('csv') का आह्वान करते हैं तो यह मान को एक पाइथन स्ट्रिंग के रूप में कुंजी सीएसवी से संबद्ध करता है। एक पायथन स्ट्रिंग फ़ाइल जैसी वस्तु नहीं है। जाहिर है, csv मॉड्यूल गिर रहा है जब यह ऑब्जेक्ट को समझ में नहीं आता है और इसे फिर से सक्रिय करता है (पायथन में तारों को चरित्र द्वारा पुनरावृत्त किया जा सकता है, उदाहरण के लिए, for c in 'Test String': print c स्ट्रिंग में प्रत्येक वर्ण को एक अलग पंक्ति पर प्रिंट करेगा)।

सौभाग्य से, पायथन StringIO कक्षा प्रदान करता है जो एक स्ट्रिंग को फ़ाइल जैसी वस्तु के रूप में माना जा सकता है। तो (यह मानते हुए GAE StringIO का समर्थन करता है, और कोई कारण नहीं है कि यह नहीं होना चाहिए है) यदि आप ऐसा करने में सक्षम होना चाहिए:

class ProcessUpload(webapp.RequestHandler): 
    def post(self): 
    self.response.out.write(self.request.get('csv')) 

    # Iterating over a string as a file 
    stringReader = csv.reader(StringIO.StringIO(self.request.get('csv'))) 
    for row in stringReader: 
     self.response.out.write(row) 

के रूप में आप यह करने की उम्मीद कौन सा काम करेंगे।

संपादित मैं यह सोचते कर रहा हूँ कि तुम एक <textarea/> की तरह कुछ का उपयोग कर रहे csv फ़ाइल लेने के लिए। यदि आप एक अनुलग्नक अपलोड कर रहे हैं, तो अलग-अलग हैंडलिंग आवश्यक हो सकती है (मैं पाइथन जीएई से परिचित नहीं हूं या यह अनुलग्नक को कैसे संभालता है)।

+0

धन्यवाद! इसने इसे हल किया, और आपके स्पष्टीकरण को समझने के लिए मेरे लिए बहुत आसान था। –

+0

@ अगस्त फ़्लानगन मुझे वाक्य में व्यक्त विचार नहीं लगता ** पायथन सीएसवी मॉड्यूल फ़ाइल जैसी वस्तुओं पर काम करता है, यह एक फ़ाइल या कुछ है जो एक पायथन फ़ाइल की तरह व्यवहार करता है। इसलिए, csv.reader() को फ़ाइल ऑब्जेक्ट प्राप्त करने की अपेक्षा है क्योंकि यह केवल आवश्यक पैरामीटर है। ** सही होना। दस्तावेज़ीकरण कहता है _ "csv.reader (csvfile, dialect = 'excel', ** fmtparams) एक पाठक ऑब्जेक्ट लौटाएं जो दिए गए csvfile में लाइनों पर पुनरावृत्ति करेगा। Csvfile कोई ऑब्जेक्ट हो सकता है जो इटरेटर प्रोटोकॉल का समर्थन करता है और प्रत्येक स्ट्रिंग देता है समय की अगली() विधि को "_ – eyquem

+0

@AugustFlanagan कहा जाता है, इसलिए यह स्पष्ट है कि' csv.reader (x) '' किसी ऑब्जेक्ट 'x'' पर चल रहा है जो आवश्यक रूप से फ़ाइल जैसी वस्तु नहीं है, केवल आवश्यकता है कि 'x'' एक पुनरावृत्त होना चाहिए और पुनरावृत्त होने पर स्ट्रिंग स्ट्रिंग होना चाहिए। – eyquem

0

आपको csv_file = self.request.POST.get("csv_import") और csv_file = self.request.get("csv_import") पर कॉल करने की आवश्यकता है।

दूसरा एक आपको केवल एक स्ट्रिंग देता है जैसा आपने अपनी मूल पोस्ट में उल्लेख किया है। लेकिन self.request.POST.get के माध्यम से पहुंचने से आपको cgi.FieldStorage ऑब्जेक्ट मिलता है।

इसका मतलब है कि आप माइक्रेटेप प्राप्त करने के लिए ऑब्जेक्ट के फ़ाइल नाम और csv_file.type प्राप्त करने के लिए csv_file.filename पर कॉल कर सकते हैं। इसके अलावा, यदि आप csv_file.file तक पहुंचते हैं, तो यह एक स्ट्रिंगओ ऑब्जेक्ट (StringIO module से केवल पढ़ने योग्य ऑब्जेक्ट) है, केवल एक स्ट्रिंग नहीं। his answer में वर्णित ig0774 के रूप में, स्ट्रिंगियो मॉड्यूल आपको एक स्ट्रिंग को फ़ाइल के रूप में पेश करने की अनुमति देता है।

इसलिए, अपने कोड बस हो सकता है:

class CSVImport(webapp.RequestHandler): 
    def post(self): 
    csv_file = self.request.POST.get('csv_import') 
    fileReader = csv.reader(csv_file.file) 
    for row in fileReader: 
     # row is now a list containing all the column data in that row 
     self.response.out.write(row)