2017-08-30 13 views
0

私は現在、SMTPサーバーからログファイルを読み込み、渡されるすべての電子メールに関する意味のある情報を抽出するプロジェクトを行っています。私は後で検索のために関連するいくつかの列を持つテーブルを持っています。ドメインから、ドメイン、タイムスタンプ、件名など 通常、(期待どおり)件名フィールドにある非ASCII文字に遭遇するまで、すべて正常に動作します。ユニコードをsqliteに保存する際の問題

strをiso-8859-1(ファイルのエンコード)にデコードして保存しようとしましたが、それを保存して、UTF-8にエンコードしようとしました。正に、私はここで少し失われています。私は、Python 2.7でユニコードを扱うことは悪夢だと聞いたことがありますが、これまでに経験したことはありません。

とにかく、私に説明させてください。これは、件名を抽出する方法です。

if 'subject' in realInfo: 
emailDict[keywrd].setSubject(realInfo[realInfo.index('subject') + 
len('subject') + 1:].decode('ISO-8859-1')) 

emailDictは処理中のすべての電子メールを含む辞書です。

そして、これは私がデータベースにすべてのものを挿入しています方法です:私は、問題がどこにあるか私が理解するために2つのprint文を追加しました

info = (e.getID(), str(e.getSpamScore()), str(e.getMCPScore()), " ".join(e.getFrom()), " ".join(e.getTo()), e.getStatus(), e.getTimestamp(), e.getSubject(), dumps(e)) 
    print repr(e.getSubject()) # DEBUG 
    print type(e.getSubject()) # DEBUG 
    self.conn.cursor().execute(u"INSERT INTO emails (emailID, SpamScore, MCPScore, FromDomain, ToDomain, status, timestamp, subject, object)" 
         " VALUES (?,?,?,?,?,?,?,?,?)", info) 
    self.conn.commit() 

「e」はすべての電子メールの青写真として機能する電子メールオブジェクトです。以前は通訳者によって得られた情報が含まれています。その後、私は、以前にも述べたように、検索に使用される列(ここでは「オブジェクト」列は電子メールオブジェクトで、ここではピクルを使用します)に最も重要な情報を保存しています。しかし、特殊文字が表示されるとすぐに、例外が発生します

u'VPXL \xffM-^W no more compromises. Better size, better life. \n' 
<type 'unicode'> 
Exception in thread Thread-25: 
Traceback (most recent call last): 
File "/usr/local/lib/python2.7/threading.py", line 801, in __bootstrap_inner 
self.run() 
File "/usr/local/lib/python2.7/threading.py", line 754, in run 
self.__target(*self.__args, **self.__kwargs) 
File "/ProjMail/projMail_lib.py", line 174, in refresher 
self.interpreter.start() 
File "/ProjMail/projMail_lib.py", line 213, in start 
c.save(self.emailTracker) 
File "/ProjMail/projMail_lib.py", line 56, in save 
self.saveEmails() 
File "/ProjMail/projMail_lib.py", line 62, in saveEmails 
else: self.add(key) # If it's new 
File "/ProjMail/projMail_lib.py", line 82, in add 
" VALUES (?,?,?,?,?,?,?,?,?)", info) 

ProgrammingError: You must not use 8-bit bytestrings unless you use a 
text_factory that can interpret 8-bit bytestrings (like text_factory = str). 
It is highly recommended that you instead just switch your application to 
Unicode strings.   

私が見たものから、それはユニコードなので、sqliteのが不平を言っている理由を私は理解できません。 私はここで間違っているかもしれない何か考えていますか?前もって感謝します!

答えて

0

問題は、被験者自身をデータベースに挿入することではなく、節約されたEmailインスタンスを挿入することです。 Emailインスタンスをピッキング

>>> subject = u'VPXL \xffM-^W no more compromises. Better size, better life. \n' 
>>> conn = sqlite3.connect(':memory:') 
>>> c = conn.cursor()        
>>> c.execute("""CREATE TABLE foo (bar text, baz text)""")         
<sqlite3.Cursor object at 0x7fab5cf280a0> 
>>> c.execute("""INSERT INTO foo VALUES (?, ?)""", (subject, 'random text')) 
<sqlite3.Cursor object at 0x7fab5cf280a0> 

>>> class Email(object):pass 
... 
>>> e = Email() 
>>> e.subject = subject 
>>> c.execute("""INSERT INTO foo VALUES (?, ?)""", (subject, pickle.dumps(e))) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
sqlite3.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings. 

は(だけでもsubjectがこれを行うだろう摘み)例外をトリガ、内部混合エンコーディングとバイト文字列を作成します。

>>> conn.text_factory = str 
>>> c.execute(stmt2, (subject, pickle.dumps(e))) 
<sqlite3.Cursor object at 0x7fab5b3343b0> 

デフォルトunicodetext_factoryを使用し続けることを好む場合は、あなたがに包まれblob列、漬けクラスを保存することができます:あなたはstrに接続のtext_factory属性を変更することができ、例外を防ぐため

bufferインスタンス。

>>> conn.text_factory = unicode 
>>> c.execute("""CREATE TABLE foo2 (bar text, baz blob)""") 
>>> c.execute("""INSERT INTO foo VALUES (?, ?)""", (subject, buffer(pickle.dumps(e))))      
<sqlite3.Cursor object at 0x7fab5b3343b0> 

漬けインスタンスが検索に復元されます。

>>> c.execute("""SELECT bar, baz FROM foo2""") 
<sqlite3.Cursor object at 0x7fab5b3343b0> 
>>> res = c.fetchone() 
>>> res 
(u'VPXL \xffM-^W no more compromises. Better size, better life. \n', <read-write buffer ptr 0x7fab5e9706c8, size 167 at 0x7fab5e970688>) 
>>> pickle.loads(res[1]) 
<__main__.Email object at 0x7fab5b333ad0> 
+0

私はあなたが提案し何をやった、それが働きました!どうもありがとう! –

関連する問題