【问题标题】:Unicode Hell in Pyramid: MySQL -> SQLAlchemy -> Pyramid -> JSONPyramid 中的 Unicode 地狱:MySQL -> SQLAlchemy -> Pyramid -> JSON
【发布时间】:2011-10-31 15:11:39
【问题描述】:

背景

我对 unicode 和 Python 感到很困惑。这似乎是一种常见的焦虑,我尝试过使用其他解决方案,但我无法理解它。

设置

MySQL 数据库设置

  • collat​​ion_database: utf8_general_ci
  • character_set_database: utf8

SQLAlchemy 模型

class Product(Base):
    id = Column('product_id', Integer, primary_key=True)
    name = Column('product_name', String(64)) #Tried using Unicode() but didn't help

金字塔视图

@view_config(renderer='json', route_name='products_search')
def products_search(request):
    json_products = []
    term = "%%%s%%" % request.params['term']

    products = dbsession.query(Product).filter(Product.name.like(term)).all()

    for prod in products:
        json_prod = {'id': prod.id, 'label': prod.name, 'value': prod.name, 'sku': prod.sku, 'price': str(prod.price[0].price)}
        json_products.append(json_prod)

    return json_products

问题

我收到来自 json 模块(称为此路由的渲染器)报告的编码错误,如下所示:

UnicodeDecodeError: 'utf8' codec can't decode byte 0x96 in position 37: invalid start byte

罪魁祸首是 prod.name 值中的“-”(破折号)。完整堆栈跟踪here。如果退回的产品中没有“-”,则一切正常!

试过

在返回 json_products 变量之前,我已经尝试过各种类型的编码、解码。

【问题讨论】:

  • 我不知道您正在使用的框架,但在某个地方,破折号(N-dash,,而不是 -)正在被编码为 cp1252(其中给出字节 0x96)。 JSON 总是处理 unicode,因此它尝试使用 UTF-8 对其进行解码,但失败了。所以在某个地方你需要.decode("cp1252")

标签: python json sqlalchemy pyramid


【解决方案1】:

above comment 是对的,但更具体地说,您可以将'label': prod.name 替换为'label': prod.name.decode("cp1252")。您可能还应该对 json_prod 字典中的所有字符串执行此操作,因为在您的应用程序的实际使用中,您很可能会在其他地方看到 cp1252 编码字符。

请注意,根据这些字符串的来源以及该来源在您的应用中使用的广泛程度,您可能会在应用的其他地方遇到此类问题,而且通常是在您最不期望的时候。为了进一步调查,您可能想弄清楚这些字符串的来源是什么,以及您是否可以在较低级别进行解码/重新编码以纠正大多数未来的问题。

【讨论】:

  • 太棒了!谢谢 - 这也有助于解决其他一些编码问题。我不明白为什么当数据库是 utf8 时它被编码为 cp1252。如果没有特别说明,MySQL 客户端默认为 latin1。即使表是utf8。我在我的数据库连接 URL 的末尾添加了“?charset=utf8”,以确保所有返回的数据都被编码为 UTF-8。那么现在在较低级别排序!再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 2013-12-31
  • 2015-02-06
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多