エラー内容
以下状況で、MongoDB
に登録できないエラーが発生しました。
状況
XML
を取得して、python Object
に変換する1.
のpython Object
をjson Object
に変換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
以上です。
コメント