注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

@fc_lamp

关注Web应用解决方案MySql/PHP/Python一盏名为"飞川"的灯~

 
 
 

日志

 
 

Python MySQL 数据库乱码解决方法  

2012-11-28 18:26:54|  分类: Web技术-Python |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
Python MySQL 数据库乱码解决方法
(注:一个工作备忘录)
你在做数据库查寻操作时,是否经常被这样的问题困扰:“ cur.execute(sql)  Warning: Incorrect string value: '\xB2\xE2\xCA\xD4\xD2\xBB...' for column 'title' at row” 。那么今天我们就是专门来解决此问题的。

 一 准备工作(如果你的MySQL已安装可不读这两篇文章) 
      在开始之前你可能需要读一下这些文章(好吧,我可能写的点乱)

二 开始工作
    1 普通情况
     看了以上文章后,你应该明白以下几点了(好吧,不明白我来说):
      1) 数据库、表、字段字符编码要一致。
      2) 程序编码、编辑器字符编码要一致。
      3) 连接数据库、查寻时字符编码要与数据库字符编码一致。
      好了,保证以上一致后,我们来一个小的测试。
      建立一个数据库,其中:数据库、表、字段字符编码都为UTF-8,字段如下:
     Python MySQL 数据库乱码解决方法 - fc_lamp - @fc_lamp
     id 自增。
    程序代码为:

#coding:utf-8
import MySQLdb

#连接服务器
conn = MySQLdb.connect(host='127.0.0.1',db='test',user='root',passwd='',
charset='utf8'
)
#查寻句柄
cur = conn.cursor()
cur.execute('SET NAMES utf8')

#插入数据
sql = "INSERT INTO test(`title`) VALUES('测试一下')"
cur.execute(sql)
conn.commit()


注意代码中的编码设置,执行这段代码后你会看到如下结果:
Python MySQL 数据库乱码解决方法 - fc_lamp - @fc_lamp

这里我们做一个小动作,把#coding:utf-8 改成 #coding:gbk 看会出现什么情况。

2 从外部导入数据时
   上面我们插入数据时,是直接写的中文在代码里,也就是说“测试一下” 是以unicode的方式传入到 execute() 方法中。
   那要是我们从一个gbk编码或者(ANSI)编码的文件里导入数据时,如何处理呐?
   我们首先用win 的记事本建立一个文本文件 test.txt ,并写入:“测试一下第二个” 内容。
   我们来看我们的代码如何写:

#coding:utf-8
import MySQLdb

#连接服务器
conn = MySQLdb.connect(host='127.0.0.1',db='test',user='root',passwd='',
charset='utf8'
)
#查寻句柄
cur = conn.cursor()
cur.execute('SET NAMES utf8')

#记取文件内容
line = ''
with open('test.txt') as f:
line = f.readline()

#插入数据
sql = "INSERT INTO test(`title`) VALUES('%s')"%(line)
cur.execute(sql)
conn.commit()

我们看到我们对代码稍作了修改,加上了文件操作的代码(更多文件操作函数参看:http://fc-lamp.blog.163.com/blog/static/1745666872011626510810/)

好了,我们执行代码看看:
    cur.execute(sql)
Warning: Incorrect string value: '\xB2\xE2\xCA\xD4\xD2\xBB...' for column 'title' at row 1

OH。。不想看到的错误出现了,原因等一会儿说。这里要提醒一下:虽然这里报错了(注意是Warning),但程序仍然会朝下进行。所以数据库中被写入了一条不合法的数据:
Python MySQL 数据库乱码解决方法 - fc_lamp - @fc_lamp
要注意这一点。
好了,现在我们来说说刚才的那错误。那么程序从文本里读取出数据是什么格式的呐?python在读取test.txt文件里的内容是会以源文件默认编码来编码字符串。即"测试一下第二个"按源文件默认编码后,成了这样的字符串: '\xb2\xe2\xca\xd4\xd2\xbb\xcf\xc2\xb5\xda\xb6\xfe\xb8\xf6'  (使用 repr() 函数可以看到真实结果) 。

因此,我们要使用源文件内容,就得将其解码成unicode对象,再来使用。

#coding:utf-8
import MySQLdb

#连接服务器
conn = MySQLdb.connect(host='127.0.0.1',db='test',user='root',passwd='',
charset='utf8'
)
#查寻句柄
cur = conn.cursor()
cur.execute('SET NAMES utf8')

#记取文件内容
line = ''
with open('test.txt') as f:
#按gbk解码成unicode对象,再编码成utf8字符串
line = f.readline().decode('gbk').encode('utf8')

#插入数据
sql = "INSERT INTO test(`title`) VALUES('%s')"%(line)
cur.execute(sql)
conn.commit()


执行此代码我们再来看结果:
Python MySQL 数据库乱码解决方法 - fc_lamp - @fc_lamp
 
不过,这里还要提一下 MySQLdb 类的cursors中的 execute(sql) 方法会自动判断是否需要转换成字符,其代码如下:

db = self._get_db()
charset = db.character_set_name()
if isinstance(query, unicode):
query = query.encode(charset)
if args is not None:
query = query % db.literal(args)

因此,较为正常的做法是:

#coding:utf-8
import MySQLdb

#连接服务器
conn = MySQLdb.connect(host='127.0.0.1',db='test',user='root',passwd='',
charset='utf8'
)
#查寻句柄
cur = conn.cursor()
cur.execute('SET NAMES utf8')

#记取文件内容
line = ''
with open('test.txt') as f:
#按gbk解码成unicode对象(这里不需要再编码一次了)
line = f.readline().decode('gbk')

#插入数据
sql = "INSERT INTO test(`title`) VALUES('%s')"%(line)
cur.execute(sql)
conn.commit()

好了,我们看一下结果:
Python MySQL 数据库乱码解决方法 - fc_lamp - @fc_lamp
 
3 输出数据时
   输出数据时,做法和写入数据是一样的(注意浏览器编码设置)。

好了,这就是全部内容。
  评论这张
 
阅读(3336)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017