пимонго:findandmodify - возвращается “такой команды нет”
Вопрос
Я полагаю, что в pymongo (или, по крайней мере, в документации) есть ошибка, которая делает невозможным запуск findandupdate
запрос.
Вот что происходит.Когда я бегу:
result = db.command({
'findandmodify': 'my_collection',
'query': {'foo': 'bar'},
'update': {'$set': {'status': 'queued'}},
})
Запрос, который фактически отправляется на сервер, является:
{ 'query': {'foo': 'bar'}, 'findandmodify': 'my_collection', … }
Обратите внимание, что query
аргумент заключается в Первый, и findandmodify
является второй.
Но это приводит к тому, что сервер выбрасывает:
OperationFailure: command { 'query': {'foo': 'bar'}, 'findandmodify': 'my_collection', … } failed: no such cmd
Потому что сервер ожидает findandmodify
быть первым (диктанты BSON, по-видимому, упорядочены).
Есть ли какой-нибудь обходной путь для этого?
Решение
Для языков, которые не имеют встроенного отсортированного типа dict, драйверы mongo включают его.В python это тип SON: http://api.mongodb.org/python/1.4%2B/api/pymongo/son.html.Вам нужно будет использовать это для всех команд.
Если это все еще не удается, убедитесь, что вы используете последнюю версию базы данных, поскольку findandmodify - это новая функция.
Другие советы
текущий pymongo api имеет встроенные функции find_and_modify смотрите больше на https://github.com/mongodb/mongo-python-driver/blob/master/pymongo/collection.py#L1035
Одним из обходных путей может быть создание JavaScript-версии команды и передача ее в db.eval().
db.eval('db.runCommand({"findandmodify": "my_collection", "query": {"foo": "bar"}, "update": {"$set": {"status": "queued"}},})')
Проблема в том, что, как упоминал Алекс, в Python dicts нет порядка, поэтому вам нужно будет более или менее построить строку вручную.
Смотрите документацию PyMongo:
Обратите внимание, что порядок клавиш в командном документе имеет значение ( “глагол” должен быть первым), поэтому команды, требующие нескольких клавиш (напримерfindandmodify) следует использовать экземпляр SON или строку и kwargs вместо Python dict.