3

さまざまなソースからデータを読み取り、MongoDB に保存するシステムがあります。受け取ったデータは、すでに utf-8 または unicode で適切にエンコードされています。ドキュメントは大まかに関連しており、必要に応じてスキーマが大きく異なります。

ドキュメントには、JPEG 画像のような純粋なバイナリ データのフィールド値が含まれることがあります。例外bson.binary.Binaryを回避するために、その値をオブジェクトにラップする方法を知っています。bson.errors.InvalidStringData

ドキュメントのどの部分で pymongo ドライバーがbson.errors.InvalidStringData.

(+バイナリ オブジェクトがたまたま有効な Unicode 文字列または utf-8 である場合、それは文字列として格納され、問題ありません)

4

2 に答える 2

4

PyMongo には 2 つの BSON 実装があり、1 つは移植性のために Python で、もう 1 つは速度のために C で実装されています。_make_c_stringPythonバージョンでは、エンコードに失敗したものを教えてくれますが、明らかに使用しているものであるCバージョンではわかりません。を使用して、どの BSON 実装を使用しているかを確認できますimport bson; bson.has_c()PYTHON-533を提出しました。すぐに修正されます。

于 2013-06-04T14:01:40.593 に答える
1

(私自身の質問に答える)

例外から判断することはできません。その機能をサポートするには、ドライバーを書き直す必要があります。

コードは にありbson/__init__.pyます。文字列が utf-8 でエンコードされる場合、文字列が UnicodeError をスローする_make_c_stringと発生するという名前の関数があります。文字列であるキーと値の両方にInvalidStringData同じ関数が使用されます。

つまり、コードのこの時点では、ドライバーはキーまたは値を処理しているかどうかを認識していません。

問題のあるデータ生の文字列として例外のコンストラクターに渡されますが、理由がわかりませんが、ドライバーから出てきません。

>>> bad['zzz'] = '0\x82\x05\x17'
>>> try:
...     db.test.insert(bad)
... except bson.errors.InvalidStringData as isd:
...     print isd
...
strings in documents must be valid UTF-8

しかし、それは問題ではありません。とにかく、その値のキーを検索する必要があります。

最善の方法は、値を反復処理して、utf-8 でデコードすることです。aUnicodeDecodeErrorが発生した場合、値を Binary オブジェクトでラップします。

ややこのように:

try:
    #This code could deal with other encodings, like latin_1
    #but that's not the point here
    value.decode('utf-8')
except UnicodeDecodeError:
    value = bson.binary.Binary(str(value))
于 2013-05-28T20:53:01.067 に答える