2009-06-08 16 views
8

के साथ यूनिकोड समस्या मुझे पता है कि मुझे यूनिकोड से रूपांतरण में कोई समस्या है लेकिन मुझे यकीन नहीं है कि यह कहां हो रहा है।SQLAlchemy

मैं HTML फ़ाइलों की निर्देशिका से हाल ही में यूरोपेन यात्रा के बारे में डेटा निकाल रहा हूं। कुछ स्थान नामों में गैर-ASCII वर्ण हैं (जैसे é, ô, ü)। मुझे regex का उपयोग कर फ़ाइल के स्ट्रिंग प्रस्तुति से डेटा मिल रहा है।

तो मैं स्थानों प्रिंट के रूप में मैं उन्हें मिल जाए, वे पात्रों के साथ मुद्रित इतना एन्कोडिंग ठीक होना चाहिए:

Le Pré-Saint-Gervais, France 
Hôtel-de-Ville, France 

मैं का उपयोग कर एक SQLite तालिका में डेटा भंडारण कर रहा हूँ SQLAlchemy:

Base = declarative_base() 
class Point(Base): 
    __tablename__ = 'points' 

    id = Column(Integer, primary_key=True) 
    pdate = Column(Date) 
    ptime = Column(Time) 
    location = Column(Unicode(32)) 
    weather = Column(String(16)) 
    high = Column(Float) 
    low = Column(Float) 
    lat = Column(String(16)) 
    lon = Column(String(16)) 
    image = Column(String(64)) 
    caption = Column(String(64)) 

    def __init__(self, filename, pdate, ptime, location, weather, high, low, lat, lon, image, caption): 
     self.filename = filename 
     self.pdate = pdate 
     self.ptime = ptime 
     self.location = location 
     self.weather = weather 
     self.high = high 
     self.low = low 
     self.lat = lat 
     self.lon = lon 
     self.image = image 
     self.caption = caption 

    def __repr__(self): 
     return "<Point('%s','%s','%s')>" % (self.filename, self.pdate, self.ptime) 

engine = create_engine('sqlite:///:memory:', echo=False) 
Base.metadata.create_all(engine) 
Session = sessionmaker(bind = engine) 
session = Session() 

फ़ाइलों के माध्यम से मैं पाश और डेटाबेस में हर एक से डेटा सम्मिलित करें:

for filename in filelist: 

    # open the file and extract the information using regex such as: 
    location_re = re.compile("<h2>(.*)</h2>",re.M) 
    # extract other data 

    newpoint = Point(filename, pdate, ptime, location, weather, high, low, lat, lon, image, caption) 
    session.add(newpoint) 
    session.commit() 

मैं प्रत्येक डालने पर निम्न चेतावनी देखें:

/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/engine/default.py:230: SAWarning: Unicode type received non-unicode bind param value 'Spitalfields, United Kingdom' 
    param.append(processors[key](compiled_params[key])) 

और जब मैं इस तरह के रूप तालिका के साथ कुछ भी करने की कोशिश:

Traceback (most recent call last): 
    File "./extract_trips.py", line 131, in <module> 
    session.query(Point).all() 
    File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/orm/query.py", line 1193, in all 
    return list(self) 
    File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/orm/query.py", line 1341, in instances 
    fetch = cursor.fetchall() 
    File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/engine/base.py", line 1642, in fetchall 
    self.connection._handle_dbapi_exception(e, None, None, self.cursor, self.context) 
    File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/engine/base.py", line 931, in _handle_dbapi_exception 
    raise exc.DBAPIError.instance(statement, parameters, e, connection_invalidated=is_disconnect) 
sqlalchemy.exc.OperationalError: (OperationalError) Could not decode to UTF-8 column 'points_location' with text 'Le Pré-Saint-Gervais, France' None None 

मैं चाहूँगा:

session.query(Point).all() 

मैं सही ढंग से स्टोर करने में सक्षम होने के लिए और फिर मूल अक्षरों के साथ स्थान नामों को बरकरार रखें। कोई भी सहायताकाफी प्रशंसनीय होगी।

उत्तर

11

मैं इस लेख है कि कुछ हद तक मेरी मुसीबतों समझाने में मदद की पाया इस प्रकार है:

जब फ़ाइल खोलने:

infile = codecs.open(filename, 'r', encoding='iso-8859-1') 

जब स्थान छपाई:

print location.encode('ISO-8859-1') 

मैं अब क्वेरी और पहले से त्रुटि के बिना मेज से डेटा में हेरफेर कर सकते हैं। जब मैं टेक्स्ट आउटपुट करता हूं तो मुझे बस एन्कोडिंग निर्दिष्ट करना होगा।

(मैं अभी भी पूरी तरह से समझ में नहीं है कि यह कैसे इतना काम कर रहा है मुझे लगता है कि यह अजगर का यूनिकोड से निपटने के बारे में अधिक जानने के लिए समय आ गया है ...)

+1

मैं "आईएसओ -885 9 -1" से पहले "सीपी 1252" पहले कोशिश करूंगा। और मुझे नहीं पता कि निम्नलिखित में क्या मदद करता है: http://stackoverflow.com/questions/368805/python-unicodedecodeerror-am-i-misunderstanding-encode/370199#370199 – tzot

7

यूनिकोड स्तंभों के लिए स्ट्रिंग के बजाय यूनिकोड का एक स्तंभ प्रकार का उपयोग कर प्रयास करें:

Base = declarative_base() 
class Point(Base): 
    __tablename__ = 'points' 

    id = Column(Integer, primary_key=True) 
    pdate = Column(Date) 
    ptime = Column(Time) 
    location = Column(Unicode(32)) 
    weather = Column(String(16)) 
    high = Column(Float) 
    low = Column(Float) 
    lat = Column(String(16)) 
    lon = Column(String(16)) 
    image = Column(String(64)) 
    caption = Column(String(64)) 

संपादित करें: रिस्पांस टिप्पणी करने के लिए:

आप यूनिकोड एनकोडिंग के बारे में चेतावनी मिल रहे हैं तो वहाँ दो चीजें हैं आप कोशिश कर सकते हैं:

  1. अपने स्थान को यूनिकोड में कनवर्ट करें।

    newpoint = प्वाइंट (फ़ाइल नाम, pdate, ptime, यूनिकोड (स्थान), मौसम, उच्च, निम्न, अक्षां, देशांतर, छवि, शीर्षक)

    यूनिकोड रूपांतरण: यह आपके प्वाइंट इस तरह बनाया होने का मतलब होगा एक स्ट्रिंग या यूनिकोड स्ट्रिंग पास करते समय एक यूनिकोड स्ट्रिंग का उत्पादन करेगा, इसलिए आपको जो भी गुजरता है उसके बारे में चिंता करने की आवश्यकता नहीं है।

  2. यदि यह एन्कोडिंग समस्याओं को हल नहीं करता है, तो अपने यूनिकोड पर एन्कोड को कॉल करने का प्रयास करें वस्तुओं। इसका मतलब कोड का उपयोग करना होगा:

    न्यूपॉइंट = प्वाइंट (फ़ाइल नाम, पीडीएटी, पीटाइम, यूनिकोड (स्थान) .encode ('utf-8'), मौसम, उच्च, निम्न, लेट, लोन, छवि, कैप्शन)

    यह चरण शायद आवश्यक नहीं होगा लेकिन यह अनिवार्य रूप से जो करता है वह यूनिकोड कोड-पॉइंट्स से एक विशिष्ट बाइट प्रतिनिधित्व (इस मामले में, utf-8) में एक यूनिकोड ऑब्जेक्ट को परिवर्तित करता है। जब आप यूनिकोड ऑब्जेक्ट्स में जाते हैं तो मुझे लगता है कि यह आपके लिए ऐसा करने के लिए स्क्लेक्लेमी को ऐसा करने की उम्मीद है लेकिन ऐसा नहीं हो सकता है।

+0

सुझाव के लिए धन्यवाद। मुझे लगता है कि यह मुझे सही दिशा में ले जा रहा है। अब मैं जो डेटा डाल रहा हूं उसके एन्कोडिंग के बारे में चेतावनियां प्राप्त कर रहा हूं लेकिन मुझे यह ठीक नहीं है कि इसे कैसे ठीक किया जाए। मैंने आपके सुझाव को दर्शाने के लिए अपना प्रश्न अपडेट कर लिया है। –

7

sqlalchemy.org से

देखें खंड 0.4.2

स्ट्रिंग और create_engine(), ज़ोर _unicode के लिए नया झंडा जोड़ा = (यह सच है | झूठी | 'चेतावनी दी है' | कोई नहीं) । False या None पर पर यूनिकोड प्रकार पर _engine() और स्ट्रिंग, 'warn' बनाएं। True, परिणामस्वरूप सभी यूनिकोड रूपांतरण संचालन अपवाद को बढ़ाते हैं जब गैर-यूनिकोड बायटेस्ट्रिंग को बाइंड पैरामीटर के रूप में पास किया जाता है। एक चेतावनी में 'चेतावनी' परिणाम परिणाम। यह दृढ़ता से सलाह दी जाती है कि सभी यूनिकोड-जागरूक अनुप्रयोग पायथन यूनिकोड ऑब्जेक्ट्स (यानी यू'हेलो 'और ' हैलो 'का उचित उपयोग नहीं करते हैं) ताकि डेटा राउंड सही तरीके से यात्रा कर सके।

मुझे लगता है कि आप एक गैर-यूनिकोड बाइटस्ट्रिंग इनपुट करने की कोशिश कर रहे हैं। शायद यह आपको सही रास्ते पर ले जा सकता है? कुछ प्रकार के रूपांतरण की आवश्यकता है, 'हैलो' और यू'हेलो 'की तुलना करें।

http://www.amk.ca/python/howto/unicode#reading-and-writing-unicode-data

मैं 'कोडेक्स' मॉड्यूल का उपयोग कर और उसके बाद के रूप में मेरे कार्यक्रम बदलकर वांछित परिणाम प्राप्त करने में सक्षम था:

चीयर्स