4

我在我的应用程序中遇到编码问题,并且在网络上的任何地方都没有找到解决方案。

这是场景:

  • 带有 UTF-8 编码的 PostgreSQL ( CREATE DATABASE xxxx WITH ENCODING 'UTF8')

  • Python 逻辑也使用 UTF-8 编码 ( # -*- coding: utf-8 -*-)

  • Jinja2 显示我的 HTML 页面。Python 和 Jinja2 用于 Flask,这是我正在使用的微框架。

我的页面标题有:<meta http-equiv="content-type" content="text/html; charset=utf-8"/>

好吧,使用 psycopg2 做一个简单的查询并在 Jinja2 上打印出来,这就是我得到的:

{% for company in list %}
    <li>
        {{ company }}
    </li>
{% endfor %}

(1, 'Casa das M\xc3\xa1quinas', 'R. Tr\xc3\xaas, Mineiros - Goi\xc3\xa1s')

(2, 'Ar do Z\xc3\xa9', 'Av. S\xc3\xa9tima, Mineiros - Goi\xc3\xa1s')

如果我尝试更深入地了解这些领域:

{% for company in list %}
    <li>
        {% for field in company %}
            <li>
                {{ field }}
            </li>
        {% endfor %}
    </li>
 {% endfor %}

我收到以下错误:UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)

但是,如果我在将列表字段发送到 Jinja2 之前打印它们,我会得到预期的结果(这也是在 postgresql 中呈现的方式):

1 Casa das Máquinas R. Três, 米内罗斯 - 戈亚斯

2 Ar do Zé Av. Sétima,米内罗斯 - 戈亚斯

当我收到错误消息时,Flask 提供了一个“调试”选项。这是代码在转义返回标记(unicode(s)

我也可以这样做:

[console ready]

>>> print s
Casa das Máquinas

>>> s
'Casa das M\xc3\xa1quinas'

>>> unicode(s)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)

>>> s.decode('utf-8')
u'Casa das M\xe1quinas'

>>> s.encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)

>>> s.decode('utf-8').encode('utf-8')
'Casa das M\xc3\xa1quinas'

>>> print s.decode('utf-8').encode('utf-8')
Casa das Máquinas

>>> print s.decode('utf-8')
Casa das Máquinas

在将其发送到 Jinja2 之前,我已经尝试在 python 代码中破坏列表、解码、编码。同样的错误。

Sooo,不知道我能在这里做什么。=(

提前致谢!

4

1 回答 1

8

问题是psycopg2在 Python 2 中默认返回字节字符串

从数据库读取数据时,在 Python 2 中,返回的字符串通常是str在数据库客户端编码中编码的 8 位对象

所以你可以:

  • 手动将所有数据解码为 UTF-8:

    # Decode the byte strings into Unicode objects using
    # the encoding you know that your database is using.
    companies = [company.decode("utf-8") for company in companies]
    return render_template("companies.html", companies=companies)
    

或者

  • 首次导入 psycopg2 时根据手册同一部分中的注释设置编码器:

    注意在 Python 2 中,如果您想统一接收所有 Unicode 格式的数据库输入,您可以在导入 Psycopg 后立即全局注册相关的类型转换:

    import psycopg2
    import psycopg2.extensions
    psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
    psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
    

    然后忘记这个故事。

于 2013-02-15T02:25:24.223 回答