Python & MySql:Unicode 和编码
Posted
技术标签:
【中文标题】Python & MySql:Unicode 和编码【英文标题】:Python & MySql: Unicode and Encoding 【发布时间】:2012-01-12 00:47:54 【问题描述】:我正在解析 json 数据并尝试将一些 json 数据存储到 mysql 数据库中。我目前收到以下 unicode 错误。我的问题是我应该如何处理这个问题。
我应该从数据库端处理它吗?如果可以,我该如何修改我的表? 我应该从 python 端处理它吗?这是我的表结构
CREATE TABLE yahoo_questions (
question_id varchar(40) NOT NULL,
question_subj varbinary(255),
question_content varbinary(255),
question_userId varchar(40) NOT NULL,
question_timestamp varchar(40),
category_id varbinary(20) NOT NULL,
category_name varchar(40) NOT NULL,
choosen_answer varbinary(255),
choosen_userId varchar(40),
choosen_usernick varchar(40),
choosen_ans_timestamp varchar(40),
UNIQUE (question_id)
);
通过python代码插入时出错:
Traceback (most recent call last):
File "YahooQueryData.py", line 78, in <module>
+"VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", (row[2], row[5], row[6], quserId, questionTime, categoryId, categoryName, qChosenAnswer, choosenUserId, choosenNickName, choosenTimeStamp))
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/MySQLdb/cursors.py", line 159, in execute
query = query % db.literal(args)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/MySQLdb/connections.py", line 264, in literal
return self.escape(o, self.encoders)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/MySQLdb/connections.py", line 202, in unicode_literal
return db.literal(u.encode(unicode_literal.charset))
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 204-230: ordinal not in range(256)
Python 代码段:
#pushing user id to the url to get full json stack
urlobject = urllib.urlopen(base_url.format(row[2]))
qnadatajson = urlobject.read()
data = json.loads(qnadatajson)
cur.execute("INSERT INTO yahoo_questions (question_id, question_subj, question_content, question_userId, question_timestamp,"
+"category_id, category_name, choosen_answer, choosen_userId, choosen_usernick, choosen_ans_timestamp)"
+"VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", (row[2], row[5], row[6], quserId, questionTime, categoryId, categoryName, qChosenAnswer, choosenUserId, choosenNickName, choosenTimeStamp))
json结构
questions: [
Id: "20111201185322AA5HTDc",
Subject: "what are the new pokemon call?",
Content: "I used to know them I stop at dialga and palkia version and I heard there's new ones what's it call
",
Date: "2011-12-01 18:53:22",
Timestamp: "1322794402",
在运行查询之前我还做了什么,我在 mysql SET character_set_client = utf8
上执行了以下操作
这就是 mysql 变量的样子:
mysql> SHOW variables LIKE '%character_set%';
+--------------------------+--------------------------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql-5.5.10-osx10.6-x86_64/share/charsets/ |
+--------------------------+--------------------------------------------------------+
8 rows in set (0.00 sec)
【问题讨论】:
通常的“让mysql接受utf8”的咒语是确保SET NAMES 'utf8'
是您打开连接时的第一个查询。你试过用character_set_client
代替吗? (这只是一条评论,因为根据您的 var 输出,我认为这不是问题所在。我认为您的 MYSQLdb Python 库正在尝试编码为 latin-1 并且不知道它应该编码为 utf-8 . 检查文档,看看是否有某种方法可以告知它这一事实。)
您的问题在于 %s,您正在尝试将 unicode 数据转换为字符串。我有同样的问题,只是不知道如何解决它......
【参考方案1】:
我认为您的 MYSQLdb python 库不知道它应该编码为 utf8,并且正在编码为默认的 python 系统定义字符集latin1
。
当您将connect()
传递给您的数据库时,传递charset='utf8'
参数。这也应该使手动 SET NAMES
或 SET character_set_client
不必要。
【讨论】:
con = mdb.connect('localhost', 'XXXX', 'XXXX', 'XXXX', unix_socket='/tmp/mysql.sock', charset='utf8') 这是什么你是说……? 这就是我的意思。但是,我现在不确定您是否还需要SET NAMES utf8
。我会尝试两者。
现在我在 300 条记录后遇到了奇怪的 json 错误。很奇怪,但这是一个很大的帮助。
好问题不,我没有删除 SET character_set_client=utf8 我没有做 SET NAMES utf8
经过 4 小时的调试/谷歌搜索,你救了我!在我的情况下,我在连接到 db 时丢失了 charset='utf8mb4'
。【参考方案2】:
首先,确保在建立 MySQL 连接时分配了 charset
和 use_unicode
参数:
conn = mysql.connect(host='127.0.0.1',
user='user',
passwd='passwd',
db='db',
charset='utf8',
use_unicode=True)
其次,在实际查询数据库时使用prepared statements。下面是一个包含 unicode 字符的字符串的示例 INSERT 查询。
cursor.execute('INSERT INTO mytable VALUES (null, %s)',
('Some string that contains unicode: ' + unichr(300),))
【讨论】:
其他答案均未提及准备好的语句问题;这就是我的诀窍。相关:要使用 %s 等在 python 格式字符串中转义百分号,例如对于使用 LIKE 或日期格式的查询,请使用双百分号 %%以上是关于Python & MySql:Unicode 和编码的主要内容,如果未能解决你的问题,请参考以下文章
用ofstream/ifstream 读写Unicod的TXT
编码(ACSII unicod UTF-8)QT输出中文乱码深入分析