エラー内容

以下状況で、MongoDB登録できないエラーが発生しました。

状況

  1. XML取得して、python Object変換する
  2. 1.python Object json Object変換
  3. 2.作成したjson Object MongoDB登録

エラー出力

.virtualenvs/v3.4.3/lib/python3.4/site-packages/pymongo/helpers.py", line 301, in _check_write_command_response
    raise WriteError(error.get("errmsg"), error.get("code"), error)
pymongo.errors.WriteError: The dotted field ...


原因

MongoDBのキー値の制約に依るエラーです。
Javaで自分自身が同じような問題ぶつかっていました。 .と、$原因で落ちていたので、キー値に含まれる場合、別の文字列に変換する方向で対応しました。 $含まれる場合は、以下のエラーが出力され落ちました。

$含まれる場合のエラー

.virtualenvs/v3.4.3/lib/python3.4/site-packages/pymongo/helpers.py", line 301, in _check_write_command_response
    raise WriteError(error.get("errmsg"), error.get("code"), error)
pymongo.errors.WriteError: The dollar ($) prefixed field '$' in ' ...


対応

remove_dots メソッドで、辞書のキー値に含まれる. $別の文字列に変換するようにしました。
remove_dots元ネタはこちら参考にしました。
$変換しているので、remove_dots ではなくなっていますが、
list 内に辞書が含まれるケースもあったので、if 文を追加しています。

def remove_dots(data):
    for key in data.keys():
        if type(data[key]) is dict: data[key] = remove_dots(data[key])
        if type(data[key]) is list:
            for i, v in enumerate(data[key]):
                if type(v) is dict:
                    v = remove_dots(v)
                    data[key][i] = v

        if '.' in key:
            data[key.replace('.', '_')] = data[key]
            del data[key]
        if '$' in key:
            data[key.replace('$', '@dollar@')] = data[key]
            del data[key]
    return data

以上です。

コメント