【问题标题】:How to fetch and print utf-8 data from mysql DB using Python?如何使用 Python 从 mysql DB 中获取和打印 utf-8 数据?
【发布时间】:2014-12-03 15:45:10
【问题描述】:

我在使用 Python 从 MySQL 数据库读取 utf-8 数据时遇到问题。我的数据库包含一个名为Videos 的表,并且该表包含至少一个具有 Unicode 字符的行,即

[KR] 三星 Galaxy Beam 2 간단 리뷰 [4K]

表格的排序规则是utf8_general_ci,就像表格中字段的排序规则一样。

这是我为了从我的表中获取所有数据而编写的代码:

# Open database connection
db = MySQLdb.connect("localhost","matan","pass","youtube", charset = 'utf8',use_unicode=True)

# prepare a cursor object using cursor() method
cursor = db.cursor()

# Prepare SQL query to INSERT a record into the database.
sql = "SELECT * FROM VIDEOS"
try:
   # Execute the SQL command
   cursor.execute(sql)
   # Fetch all the rows in a list of lists.
   results = cursor.fetchall()
   for row in results:
      title = row[0]
      link = row[1]
      # Now print fetched result
      print ("title=%s\nlink=%s\n\n" % \
            (title, link))
except:
   print "Error: unable to fecth data"

# disconnect from server
db.close()

当我运行上面的代码时,它会打印所有只包含“ascii”字符的行,但是当它到达包含 Unicode 字符的行(即我上面提到的行)时,它会打印:

File "C:\Users\Matan\Dropbox\Code\Python\youtube.py", line 28, in printall (title, link)) File "C:\Python27\lib\encodings\cp862.py", line 12, in encode return codecs.charmap_encode(input,errors,encoding_map) UnicodeEncodeError: 'charmap' codec can't encode characters in position 33-34: c haracter maps to <undefined>

并且不会继续到下一行。

我正在使用 PhpMyAdmin 4.1.14 版、MySQL 5.6.17 版和 Python 2.7.8 版。

编辑:我删除了 except 子句,并更新了我遇到的错误。

【问题讨论】:

  • 如果你真的想知道哪里出了问题,首先摆脱这个无用的裸 except 子句,让真正的异常传播。然后请回来并发布完整的回溯。仅作记录:由于您将use_unicode=True 传递给您的连接,因此您从数据库返回的所有内容都是unicode 字符串(输入Unicode,而不是输入str)。您必须在打印它们之前将它们编码为正确的编码(正确的编码取决于系统)。
  • 我根据您的建议编辑了我的问题。谢谢。

标签: python mysql unicode utf-8


【解决方案1】:

您的问题在于您的终端 (sys.stdout) 编码 (cf http://en.wikipedia.org/wiki/Code_page_862),这取决于您的系统设置。最好的解决方案(如此处所述:https://stackoverflow.com/a/15740694/41316)是在将 unicode 数据打印到sys.stdout 之前对其进行显式编码。

如果您不能使用更有用的编码(想到 utf-8,因为它旨在处理所有 unicode 字符),您至少可以使用替代错误处理,例如“替换”(替换非'?' 的可编码字符)或“忽略”(抑制不可编码的字符)。

这是您的代码的更正版本,您可以使用encodingon_error 设置来找出适合您的解决方案:

import sys
import MySQLdb

# set desired output encoding here
# it looks like your default encoding is "cp862"
# but you may want to first try 'utf-8' first
# encoding = "cp862"
encoding = "utf-8" 

# what do when we can't encode to the desired output encoding
# options are:
# - 'strict' : raises a UnicodeEncodeError (default)
# - 'replace': replaces missing characters with '?'
# - 'ignore' : suppress missing characters
on_error = "replace" 

db = MySQLdb.connect(
   "localhost","matan","pass","youtube", 
   charset='utf8',
   use_unicode=True
   )
cursor = db.cursor()
sql = "SELECT * FROM VIDEOS"
try:
   cursor.execute(sql)
   for i, row in enumerate(cursor):
      try:
         # encode unicode data to the desired output encoding
         title = row[0].encode(encoding, on_error)
         link = row[1].encode(encoding, on_error)
      except UnicodeEncodeError as e:
         # only if on_error='strict'
         print >> sys.stderr, "failed to encode row #%s - %s" % (i, e)
      else:
         print "title=%s\nlink=%s\n\n" % (title, link))
finally:
   cursor.close()
   db.close()

注意:您可能还想阅读这篇文章(尤其是 cmets)http://drj11.wordpress.com/2007/05/14/python-how-is-sysstdoutencoding-chosen/,了解有关 Python、字符串、unicode、编码、sys.stdout 和终端问题的更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    相关资源
    最近更新 更多