3

Django を使用して Postgres データベースを管理しています。スペイン (マラガ) の都市を表す値がデータベースに格納されています。from __future__ import unicode_literals私の Django プロジェクトでは、作成した各ファイルの先頭に配置することで、すべてに Unicode 文字列を使用しています。

XMLデータベースから都市情報を取得し、リクエストを使用して別のサーバーに送信する必要があります。データの流れを観察できるように、途中でログを記録しています。都市の値をログに記録しようとすると、次のトレースバックが表示されます。

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 1: ordinal not in range(128)

渡す値をログに記録するために使用するコードを次に示します。

def createXML(self, dict):
    """
    ..  method:: createXML()

        Create a single-depth XML string based on a set of tuples

        :param dict: Set of tuples (simple dictionary)
    """

    xml_string = ''
    for key in dict:
        self.logfile.write('\nkey = {0}\n'.format(key))
        if (isinstance(dict[key], basestring)):
            self.logfile.write('basestring\n')
            self.logfile.write('value = {0}\n\n'.format(dict[key].decode('utf-8')))
        else:
            self.logfile.write('value = {0}\n\n'.format(dict[key]))

        xml_string += '<{0}>{1}</{0}>'.format(key, dict[key])

    return xml_string

私は基本的に、持っているすべての情報を単純な辞書に保存し、この関数を使用してXMLフォーマットされた文字列を生成しています - これはこの質問の範囲を超えています。

私が得ているエラーは、データベースに実際に何が保存されているのか疑問に思っていました. 値がutf-8エンコードされていることを確認しました。データベースから値を抽出し、デコードして画面に出力する簡単なスクリプトを作成しました。

from __future__ import unicode_literals
import psycopg2
# Establish the database connection
try:
    db = psycopg2.connect("dbname = 'dbname' \
                           user = 'user' \
                           host = 'IP Address' \
                           password = 'password'")
    cur = db.cursor()
except:
    print "Unable to connect to the database."

# Get database info if any is available
command = "SELECT state FROM table WHERE id = 'my_id'"
cur.execute(command)
results = cur.fetchall()

state = results[0][0]
print "my state is {0}".format(state.decode('utf-8'))

結果:my state is Málaga

Django では、HTTP リクエストを作成するために次のことを行っています。

## Create the header
http_header = "POST {0} HTTP/1.0\nHost: {1}\nContent-Type: text/xml\nAuthorization: Basic {2}\nContent-Length: {3}\n\n"
req = http_header.format(service, host, auth, len(self.xml_string)) + self.xml_string

reqこの情報をデータベースに書き込み、他のサーバーに送信する文字列を作成できるように、問題を修正するのを手伝ってくれる人はいますか?

Django がこれを処理する方法の結果として、このエラーが発生していますか? もしそうなら、Django は何をしていますか? または、これを引き起こしているDjangoに何をするように言っていますか?

EDIT1:django.utils.encodingこの状態値でもDjangoを使用しようとしました。Djano が unicode/utf-8 で発生する可能性のある問題について、saltycraneから少し読みました。

smart_strこの機能を使用するようにロギングを変更しようとしました。

def createXML(self, dict):
    """
    ..  method:: createXML()

        Create a single-depth XML string based on a set of tuples

        :param dict: Set of tuples (simple dictionary)
    """

    xml_string = ''
    for key in dict:
        if (isinstance(dict[key], basestring)):
            if (key == 'v1:State'):
                var_str = smart_str(dict[key])
                for index in range(0, len(var_str)):
                    var = bin(ord(var_str[index]))
                    self.logfile.write(var)
                    self.logfile.write('\n')
                self.logfile.write('{0}\n'.format(var_str))

        xml_string += '<{0}>{1}</{0}>'.format(key, dict[key])

    return xml_string

.format()これを行うことで正しい値をログに書き込むことができますが、Python の文字列機能で考えられる別の問題を絞り込みました。もちろん、私の Google 検索のpython format unicode最初の結果はIssue 7300で、これは Python 2.7 の既知の「問題」であると述べています。

さて、別のstackoverflow投稿から、Djangoで機能しない「解決策」を見つけましたsmart_str(または、少なくともそれらを連携させることができませんでした)。

引き続き掘り下げて、根本的な問題、または少なくとも回避策が見つからないかどうかを確認します。

EDIT2:機能を使用するのではなく、単に文字列を連結することで回避策を見つけました.format()。私はこの「解決策」が好きではありません - それは醜いですが、それは仕事を成し遂げました.

def createXML(self, dict):
    """
    ..  method:: createXML()

        Create a single-depth XML string based on a set of tuples

        :param dict: Set of tuples (simple dictionary)
    """

    xml_string = ''
    for key in dict:
        xml_string += '<{0}>'.format(key)
        if (isinstance(dict[key], basestring)):
            xml_string += smart_str(dict[key])
        else:
            xml_string += str(dict[key])
        xml_string += '<{0}>'.format(key)

    return xml_string

.format()意図したとおりに使用できるソリューションを見つけたいので、この質問には答えないままにします。

4

1 に答える 1

0

これは正しいアプローチです (問題はファイルを開くことにありました。UTF-8 では次を使用する必要がありますcodecs.open()

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import codecs


class Writer(object):
    logfile = codecs.open("test.log", "w", 'utf-8')

    def createXML(self, dict):
        xml_string = ''
        for key, value in dict.iteritems():
            self.logfile.write(u'\nkey = {0}\n'.format(key))
            if (isinstance(value, basestring)):
                self.logfile.write(u'basestring\n')
                self.logfile.write(u'value = {0}\n\n'.format( value))
            else:
                self.logfile.write(u'value = {0}\n\n'.format( value ))

            xml_string += u'<{0}>{1}</{0}>'.format(key, value )

        return xml_string

そして、これはpythonコンソールからのものです:

In [1]: from test import Writer

In [2]: d = { 'a' : u'Zażółć gęślą jaźń', 'b' : u'Och ja Ci zażółcę' }

In [3]: w = Writer()

In [4]: w.createXML(d)
Out[4]: u'<a>Za\u017c\xf3\u0142\u0107 g\u0119\u015bl\u0105 ja\u017a\u0144</a><b>Och ja Ci za\u017c\xf3\u0142c\u0119</b>'

そして、これはtest.logファイルです:

key = a
basestring
value = Zażółć gęślą jaźń


key = b
basestring
value = Och ja Ci zażółcę
于 2012-09-23T12:05:49.883 に答える