金字塔中的Unicode地狱:MySQL - > SQLAlchemy - >金字塔 - > JSON

Rus*_*uff 6 python json sqlalchemy pyramid

背景

我在使用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
Run Code Online (Sandbox Code Playgroud)

金字塔视图

@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
Run Code Online (Sandbox Code Playgroud)

问题

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

UnicodeDecodeError: 'utf8' codec can't decode byte 0x96 in position 37: invalid start byte
Run Code Online (Sandbox Code Playgroud)

罪魁祸首是prod.name值中的" - "(短划线符号).全堆栈跟踪这里.如果退回的产品没有" - ",那么一切正常!

试着

在返回json_products变量之前,我尝试使用各种类型进行编码和解码.

Ros*_*son 6

上述意见是正确的,但更多的specifially,可以替换'label': prod.name使用'label': prod.name.decode("cp1252").您可能也应该对json_prod字典中的所有字符串执行此操作,因为您可能会cp1252在应用程序的实际使用中看到编码字符.

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

  • 太棒了!谢谢 - 这也有助于解决其他一些编码问题.当数据库是utf8时,我无法理解为什么它在cp1252编码.当没有特别说明时,原来MySQL客户端默认为latin1.即使表是utf8.我在数据库连接URL的末尾添加了"?charset = utf8",确保所有返回的数据都被编码为UTF-8.现在排在较低的水平!再次感谢! (3认同)