4

アプリケーションでのエンコーディングに問題があり、Web上のどこにも解決策が見つかりませんでした。

シナリオは次のとおりです。

  • UTF-8エンコーディングを使用するPostgreSQL(CREATE DATABASE xxxx WITH ENCODING 'UTF8'

  • UTF-8エンコーディングを使用したPythonロジック(# -*- 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'コーデックは位置10のバイト0xc3をデコードできません:序数が範囲内にありません(128)

ただし、リストフィールドをJinja2に送信する前に印刷すると、期待どおりの結果が得られます(これは、postgresqlでの表示方法でもあります)。

1 CasadasMáquinasR.Três、ミネイロス-ゴイアス

2ArdoZéAv。ミネイロス、セティマ-ゴイアス

エラーが発生すると、Flaskは「デバッグ」するオプションを提供します。これは、コードがファイル "/home/anonimou/Desktop/flask/lib/python2.7/site-packages/jinja2/_markupsafe/_native.py"、21行目をエスケープリターン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

Jinja2に送信する前に、Pythonコードでリストを壊し、デコードし、エンコードしようとしました。同じエラー。

すっごく、ここで何ができるかわからない。=(

前もって感謝します!

4

1 に答える 1

8

問題は、Python 2 でpsycopg2 がデフォルトでバイト文字列を返すことです。

データベースからデータを読み取る場合、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 に答える