2

我使用的是:Python2.7 / MySQLdb 1.2.3

当我使用 MySQLdb.cursors 执行时INSERT IGNORE INTO reporter('张三', '2013-11-11'), ('张三', '2013-11-11')
它会出现这样的 UnicodeEncodeError 错误,它在显示警告时发生

File "/usr/local/lib/python2.7/dist-packages/MySQL_python-1.2.3-py2.7-linux-i686.egg/MySQLdb/cursors.py", line 224, in executemany
    if not self._defer_warnings: self._warning_check()
  File "/usr/local/lib/python2.7/dist-packages/MySQL_python-1.2.3-py2.7-linux-i686.egg/MySQLdb/cursors.py", line 92, in _warning_check
    warn(w[-1], self.Warning, 3)
  File "/usr/lib/python2.7/warnings.py", line 29, in _show_warning
    file.write(formatwarning(message, category, filename, lineno, line))
  File "/usr/lib/python2.7/warnings.py", line 38, in formatwarning
    s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 17-18: ordinal not in range(128)

我应该怎么办?

这是我的代码:

# -*- coding: utf-8 -*-
import MySQLdb

db_conn = MySQLdb.connect(
    host='localhost', user='root', passwd='', charset='utf8', db='test')
cursor = db_conn.cursor()
cursor.executemany(
    'INSERT IGNORE INTO unicode_test values(%s, %s)',
    [('张三', '2013-11-11'), ('张三', '2013-11-11')])
db_conn.commit()
cursor.close()
db_conn.close()

它来了

Traceback (most recent call last):
  File "/home/cooper/Document/20131106.py", line 9, in <module>
    [('张三', '2013-11-11'), ('张三', '2013-11-11')])
  File "/usr/local/lib/python2.7/dist-packages/MySQL_python-1.2.3-py2.7-linux-i686.egg/MySQLdb/cursors.py", line 224, in executemany
    if not self._defer_warnings: self._warning_check()
  File "/usr/local/lib/python2.7/dist-packages/MySQL_python-1.2.3-py2.7-linux-i686.egg/MySQLdb/cursors.py", line 92, in _warning_check
    warn(w[-1], self.Warning, 3)
  File "/usr/lib/python2.7/warnings.py", line 29, in _show_warning
    file.write(formatwarning(message, category, filename, lineno, line))
  File "/usr/lib/python2.7/warnings.py", line 38, in formatwarning
    s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 17-18: ordinal not in range(128)
[Finished in 0.2s with exit code 1]

这是我在 MariaDB 10.0 中使用的表

CREATE TABLE `unicode_test` (
 `name` varchar(10) NOT NULL,
 `date_of` date NOT NULL,
 PRIMARY KEY (`name`,`date_of`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
4

2 回答 2

4

最后,似乎我有一个线索。看来我们只是错过了跟踪中的关键点,即警告中引发了 unicode 错误,而不是在 MySQL 中。

要摆脱这种情况,您可以过滤 MySQLdb 警告添加

warnings.filterwarnings('ignore', category=MySQLdb.Warning)

到你的脚本。不知道究竟是什么警告,在我的安装中没有。您可以检查它在 mysql 控制台中手动执行查询并SHOW WARNINGS;随后运行。

或者,您可以从 修补相关函数warnings.py,使其对非 ascii 编码具有容错性,以便使用 python 进行检查。

于 2013-11-06T21:00:42.700 回答
0

显示您的表/MySQL 参数,我可以在笔记本电脑上执行此操作(字符因 cp1250 编码终端而异):

>>> MySQLdb.__version__
'1.2.3'
>>> sys.version
'2.7.2 (default, Aug 15 2012, 16:03:20) \n[GCC 4.4.3]'

$ mysqldump --no-data -ualko test unicode_test
--
-- Table structure for table `unicode_test`
--
DROP TABLE IF EXISTS `unicode_test`;
CREATE TABLE `unicode_test` (
  `name` varchar(100) DEFAULT NULL,
  `date` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

$ python test.py
$ mysql -ualko test
mysql> select * from unicode_test;
+--------+------------+
| name   | date       |
+--------+------------+
| 张三   | 2013-11-11 |
| 张三   | 2013-11-11 |
+--------+------------+
2 rows in set (0.00 sec)

更新

你的连接设置是什么?

>>> import MySQLdb
>>> db_conn = MySQLdb.connect(**settings)
>>> cursor = db_conn.cursor()
>>> cursor.execute('select @@COLLATION_CONNECTION, '
...     '@@CHARACTER_SET_RESULTS, @@CHARACTER_SET_CLIENT')
1L
>>> cursor.fetchone()
(u'utf8_general_ci', u'utf8', u'utf8')
于 2013-11-06T08:50:18.003 回答