在PostgreSQL,Python,Jinja2上编码

ano*_*mou 4 python encoding utf-8 jinja2 flask

我在我的应用程序中遇到编码问题,但在网络上找不到解决方案.

这是场景:

  • PostgreSQL使用UTF-8编码(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 %}
Run Code Online (Sandbox Code Playgroud)

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

我收到以下错误:UnicodeDecodeError:'ascii'编解码器无法解码位置10中的字节0xc3:序数不在范围内(128)

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

1 CasadasMáquinasR.Três,Mineiros - Goiás

2 ArdoZéAv.Sétima,Mineiros - Goiás

当我收到错误时,Flask提供了"调试"选项.这是代码在转义返回标记(unicode(s))中打破文件"/home/anonimou/Desktop/flask/lib/python2.7/site-packages/jinja2/_markupsafe/_native.py"第21行的地方

我也可以这样做:

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

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

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

提前致谢!

Sea*_*ira 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)
    
    Run Code Online (Sandbox Code Playgroud)

要么

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

    注意在Python 2中,如果要统一接收Unicode中的所有数据库输入,只要导入Psycopg,就可以在全局注册相关的类型代码:

    import psycopg2
    import psycopg2.extensions
    psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
    psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
    
    Run Code Online (Sandbox Code Playgroud)

    然后忘了这个故事.