エラー内容
以下状況で、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
以上です。
コメント