python sqlite的編碼問題

來源:互聯網
上載者:User
從http://initd.org/tracker/pysqlite/wiki/pysqlite下載了SQLITE
的PYTHON綁定。並用WINDOWS下的sqlite3.exe建立了一個庫一張表:
+++++++++++++++++++
-database: wanna
-table name: hello
-id name
---- ---------
0 帥哥
1 wannachan
2 dick.chan
3 雯雯
+++++++++++++++++++

好了,建表成功了!下面開始PYSQLITE來操作此資料庫了!心情那個激動啊~~
首先建立串連:
>>> from pysqlite2 import dbapi2 as sqlite
>>> con=sqlite.connect("g:\sqlite\wanna")
再啟用cursor:
>>> cur=con.cursor()
激動人心的時刻到了!執行SQL:
----------------------------------------------
>>> cur.execute('select * from hello')

Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
cur.execute('select * from hello')
OperationalError: Could not decode to UTF-8 column 'name' with text '帥哥'
----------------------------------------------

OH!NO!竟說我的‘帥哥’不能以UTF-8編碼!咋辦捏?咋辦捏?!
上網查查看!看到有人用這個con=sqlite.connect("database",encoding='cp936')
我也試試,結果:
----------------------------------------------------------------
>>> con=sqlite.connect("g:\sqlite\wanna",encoding='cp936')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'encoding' is an invalid keyword argument for this function
----------------------------------------------------------------

看來以前用的版本才有encoding這參數,現在我的2.5版沒有哇!看來只有看manual
了!於是俺萬分不情願地翻開MAN看了起來,原來是要指定text_factory才行!
於是俺試著抄它一句例子來試試:
>>> con.text_factory=lambda x: unicode(x, "utf-8", "ignore")
表示是用UTF8來編碼取得RECORD,如果非UTF-8則ignore。俺心知自己的編碼是GBK,
但也想看看會有什麼錯出現,於是繼續:
----------------------------------------------
>>> cur=con.cursor()
>>> cur.execute('select * from hello')
<pysqlite2.dbapi2.Cursor object at 0x012984A0>
>>> rs=cur.fetchall()
>>> rs[0]
(0, u'')
>>> rs[1]
(1, u'wannachan')
>>> rs[2]
(2, u'dick.chan')
>>> rs[3]
(3, u'')
----------------------------------------------
可以看到,我的兩項有中文的RECORD都由於編碼不符被忽略成了u''了,這時我
心中看到了光明!下面用GBK(CP936)來編碼試試:
----------------------------------------------
>>> con.text_factory=lambda x: unicode(x, "cp936", "ignore")
>>> cur=con.cursor()
>>> cur.execute('select * from hello')
<pysqlite2.dbapi2.Cursor object at 0x012984D0>
>>> rs=cur.fetchall()
>>> rs[0]
(0, u'\u9648\u67f1')
>>> u'\u9648\u67f1'
u'\u9648\u67f1'
>>> print rs[0][1]
帥哥
----------------------------------------------

HOHO!成功了一大步!這時我想,如果我指它UTF-8不IGNORE會怎麼樣?
說幹就幹:
----------------------------------------------
>>> con.text_factory=lambda x: unicode(x, "utf-8")
>>> cur=con.cursor()
>>> cur.execute('select * from hello')

Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
cur.execute('select * from hello')
File "<pyshell#19>", line 1, in <lambda>
con.text_factory=lambda x: unicode(x, "utf-8")
UnicodeDecodeError: 'utf8' codec can't decode byte 0xb3 in position 0:
unexpected code byte
----------------------------------------------

出錯了!說明編碼不MATCH真的不能用,那麼如果我的RECORD有多種編碼
咋辦呢?於是我嘗試用MANUAL上出現過的UNICODE OPTION來試試:
----------------------------------------------
>>> con.text_factory = sqlite.OptimizedUnicode

>>> cur=con.cursor()
>>> cur.execute('select * from hello')

Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
cur.execute('select * from hello')
OperationalError: Could not decode to UTF-8 column 'name' with text '帥哥'
>>>
----------------------------------------------

TNND,竟然UNICODE也用UTF-8來ENCODE,這不是欺負人嗎?明知UTF-8存漢字占空間大的不行!
於是俺再仔細的看MANUAL,終於看到有個是以byteString的形式傳回來的了。
俺想,這個不涉及到具體的ENCODING,應該就算有不同的CHARSET都不會有ERROR吧!
試試:
----------------------------------------------
>>> from pysqlite2 import dbapi2 as sqlite
>>> con=sqlite.connect("g:\sqlite\wanna")
>>> con.text_factory=str #str代表以byte string形式return
>>> cur=con.cursor()
>>> cur.execute('select * from hello')
<pysqlite2.dbapi2.Cursor object at 0x00BDBB30>
>>> rs=cur.fetchall()
>>> rs[0][1]
'\xb3\xc2\xd6\xf9'
>>> print rs[0][1]
帥哥
----------------------------------------------

HAHA!成功了!得到了BYTECODE STRING,就可以按指定的編碼來解碼它,就可以
得到正確的輸出了!
看看上面那個BYTECODE STRING '\xb3\xc2\xd6\xf9',試著給它解碼:
>>> '\xb3\xc2\xd6\xf9'.decode('cp936')
u'\u9648\u67f1'

果然得到了一個UNICODE串了,俺再判斷它是否等於我們預期的字串?

>>> _ == u'帥哥'
True
>>> u'帥哥'
u'\u9648\u67f1'

很明顯是一樣的串!OK,解決了!

最後的想法:
1,如果在text_factory=str之前,俺把str定義成了一個變數,override了它作
為<type 'str'>的這個身份,那會不會出錯呢?
2,喜歡用PYTHON,就是因為它的中文問題總是那麼容易解決,想將編碼怎麼轉
換就怎麼轉換!一點也不含糊!

from:http://www.cnblogs.com/changyou/archive/2010/01/09/1642980.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.