Pymongo: FindAndModify - “Nenhum comando” é retornado
Pergunta
Eu acredito que há um bug em pymongo (ou, pelo menos, a documentação) que torna impossível correr um findandupdate
consulta.
Aqui está o que acontece. Quando eu corro:
result = db.command({
'findandmodify': 'my_collection',
'query': {'foo': 'bar'},
'update': {'$set': {'status': 'queued'}},
})
A consulta que realmente é enviada para o servidor é:
{ 'query': {'foo': 'bar'}, 'findandmodify': 'my_collection', … }
Observe que o query
argumento é primeiro, e findandmodify
é segundo.
Mas isso faz com que o servidor vomite:
OperationFailure: command { 'query': {'foo': 'bar'}, 'findandmodify': 'my_collection', … } failed: no such cmd
Porque o servidor espera findandmodify
Ser o primeiro (os dictos do BSON são, aparentemente, ordenados).
Existe algum trabalho para isso?
Solução
Para idiomas que não possuem um dicto classificado embutido, os drivers Mongo incluem um. Em Python, esse é o tipo de filho: http://api.mongodb.org/python/1.4%2b/api/pymongo/son.html. Você precisará usar isso para todos os comandos.
Se isso ainda falhar, verifique se você está usando a versão mais recente do banco de dados, pois o FindAndModify é um novo recurso.
Outras dicas
A API atual do Pymongo Find_and_modify embutida, veja mais em https://github.com/mongodb/mongo-python-driver/blob/master/pymongo/collection.py#l1035
Uma solução alternativa pode ser construir a versão JavaScript do comando e passá -lo para db.eval ().
db.eval('db.runCommand({"findandmodify": "my_collection", "query": {"foo": "bar"}, "update": {"$set": {"status": "queued"}},})')
A questão é que, como Alex mencionou, os Python Dicts não têm ordem, então você precisará construir a string mais ou menos manualmente.
Veja Pymongo Documentation:
Observe que a ordem das chaves no documento de comando é significativa (o "verbo" deve vir primeiro); portanto, os comandos que exigem várias chaves (por exemplo, FindAndModify) devem usar uma instância de SON ou String e Kwargs em vez de um dicto Python.