Кодирование на PostgreSQL, Python, Jinja2

У меня проблема с кодировкой в ​​моем приложении, и я нигде не нашел решения в Интернете.

Вот сценарий:

  • 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 %}

(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 не может декодировать байт 0xc3 в позиции 10: порядковый номер не в диапазоне (128)

Однако, если я распечатаю поля списка перед отправкой их в Jinja2, я получу ожидаемый результат (который также представлен в postgresql):

1 Casa das Máquinas R. Três, Минейрос - Гояс

2 Ар-ду-Зе Авеню. Сетима, Минейрос - Гояс

Когда я получаю сообщение об ошибке, Flask предлагает возможность «отладки». Здесь код разрывается. Файл "/home/anonimou/Desktop/flask/lib/python2.7/site-packages/jinja2/_markupsafe/_native.py", строка 21, в escape-последовательности return Markup(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

Я уже пытался разбить список, декодировать, кодировать в коде Python, прежде чем отправить его в Jinja2. Та же ошибка.

Оооо, не уверен, что я могу сделать здесь. знак равно

Заранее спасибо!


person anonimou    schedule 14.02.2013    source источник
comment
это прогрессивный рок?   -  person fiatjaf    schedule 24.12.2013


Ответы (1)


Проблема в том, что psycopg2 по умолчанию возвращает байтовые строки в Python 2. :

При чтении данных из базы данных в Python 2 возвращаемые строки обычно представляют собой 8-битные объекты str, закодированные в кодировке клиента базы данных.

Итак, вы можете:

  • Вручную декодируйте все данные в 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)
    

or

  • #P5#
    #P6#
    import psycopg2
    import psycopg2.extensions
    psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
    psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
    
    #P7#
person Sean Vieira    schedule 15.02.2013
comment
Большое спасибо! Я использовал второй вариант, который для меня менее инвазивен в коде. Работал нормально. - person anonimou; 15.02.2013
comment
Великий человек, вы помогаете решить мой вопрос stackoverflow.com/questions/44347924/ - person TMoraes; 05.06.2017