最近在工作中遇到一個問題冀膝,其實(shí)是自己給自己挖了一個坑,并且還義無反顧的跳了進(jìn)去,問題描述:
在python(python 2.X) 執(zhí)行postgresql 數(shù)據(jù)插入的時候揍堕,出現(xiàn)下面這樣的情況:
其實(shí)我的postgresql 得字符編碼格式設(shè)置的是沒問題的,具體執(zhí)行
那一定是執(zhí)行插入數(shù)據(jù)的語句出了問題,查看了一下自己的插入數(shù)據(jù)命令:
def insert_tale(self, tablename, field_list, data):
self.connect_db()
cur = self.connect_db().cursor()
filed_str = '('+'%s, '*(len(field_list)-1) + '%s' +')'
filed_str = filed_str%tuple(field_list)
for i in data:
if isinstance(i, unicode):
data[data.index(i)] = i.encode('utf8')
values_ = tuple(data)
sql_ = u"insert into %s %s values %s;" % (tablename, filed_str, values_)
cur.execute(sql_)
self.commit_db()
好像也沒什么問題汤纸,重新調(diào)整了一下實(shí)現(xiàn)方式衩茸,如下是可以正常插入中文, 并可正常顯示成中文的代碼實(shí)現(xiàn)
def insert_tale(self, tablename, field_list, data):
self.connect_db()
cur = self.connect_db().cursor()
filed_str = '('+'%s, '*(len(field_list)-1) + '%s' +')'
filed_str = filed_str%tuple(field_list)
for i in data:
if isinstance(i, int):
data[data.index(i)] = str(i)
values_ = "'" + "', '".join(data) + "'"
sql_ = u"insert into %s %s values (%s);" % (tablename, filed_str, values_)
cur.execute(sql_)
self.commit_db()
具體的差別贮泞,可以看到楞慈,就是在問題代碼中,使用的list轉(zhuǎn)tuple的tuple方法啃擦,而在正常代碼中使用的是字符串的操作方式囊蓝。
兩者具體啥區(qū)別呢,舉幾個例子來觀察現(xiàn)象:
同樣是unicode編碼议惰,放在列表或者字符串后通過格式化字符串進(jìn)行轉(zhuǎn)義就不一樣了
這就是為什么在執(zhí)行insert操作的時候慎颗,如果不進(jìn)行encode轉(zhuǎn)義就會報TypeError錯誤,因?yàn)樵趕ql語句中會出現(xiàn)這樣的形式
insert into test (id, name, age, addr, phone) values (1, u"\u8fd9\u662f", 12, u"\u6d4b\u8bd5\u4ee3\u7801", '1234567890');
這是postgresql所不允許的言询。
而轉(zhuǎn)為utf-8格式后插入就會出現(xiàn)最上面圖中的數(shù)據(jù)格式俯萎,所以,在字符串轉(zhuǎn)義的時候一定要注意的就是
不要轉(zhuǎn)義list或者tuple格式的數(shù)據(jù)运杭,如果在像insert語句那樣需要(.....)的夫啊,記住(....)放在字符串中來構(gòu)建,轉(zhuǎn)義的時候辆憔,盡量只轉(zhuǎn)義字符串撇眯,數(shù)字等基本格式的數(shù)據(jù)