Acessar dados de um cursor
Nesta página
Visão geral
Neste guia, você pode aprender como acessar dados de um cursor com o PyMongo.
Um cursor é um mecanismo que retorna os resultados de uma operação de leitura em lotes iteráveis. Como um cursor contém apenas um subconjunto de documentos a qualquer momento, os cursores reduzem o consumo de memória e o uso da largura de banda da rede.
Sempre que o PyMongo executa uma operação de leitura que retorna vários documentos, ele retorna automaticamente esses documentos em um cursor.
Dados de amostra
Os exemplos neste guia usam a collection sample_restaurants.restaurants
dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de amostra, consulte o Introdução ao PyMongo.
Acesse o conteúdo do cursor iterativamente
Para iterar sobre o conteúdo de um cursor, use um loop for
, conforme mostrado no exemplo a seguir:
results = collection.find() for document in results: print(document)
Recuperar documentos individualmente
Recupere documentos de um cursor individualmente chamando o método next()
.
O exemplo a seguir encontra todos os documentos em "Dunkin' Donuts"
name
com um valor de . Em seguida, ele imprime o primeiro documento no cursor chamando o método next()
.
results = collection.find({ "name": "Dunkin' Donuts" }) print(results.next())
{'_id': ObjectId('...'), 'address': { ... }, 'borough': 'Bronx', 'cuisine': 'Donuts', 'grades': [...], 'name': "Dunkin' Donuts", 'restaurant_id': '40379573'}
Recuperar todos os documentos
Aviso
Se o número e o tamanho dos documentos retornados pela sua query excederem a memória disponível do aplicativo, seu programa falhará. Se você espera um conjunto de resultados grande, acesse o cursor iterativamente.
Para recuperar todos os documentos de um cursor, converta o cursor em um list
como mostrado no seguinte exemplo:
results = collection.find({ "name": "Dunkin' Donuts" }) all_results = list(results) for document in all_results: print(document)
Fechar um cursor
Por padrão, o MongoDB fecha um cursor quando o cliente esgota todos os resultados no cursor. Para fechar explicitamente um cursor, chame o método close()
como mostrado no exemplo a seguir:
results = collection.find() ... results.close()
Cursores persistentes
Ao fazer query em uma collection limitada, você pode usar um cursor persistente que permanece aberto depois que o cliente esgota os resultados em um cursor. Para criar um cursor persistente com collection limitada, especifique CursorType.TAILABLE_AWAIT
na opção cursor_type
de um método find()
.
O exemplo a seguir usa um cursor tailable para rastrear o oplog de um membro do conjunto de réplicas:
oplog = client.local.oplog.rs first = oplog.find().sort('$natural', pymongo.ASCENDING).limit(-1).next() print(first) ts = first['ts'] while True: cursor = oplog.find({'ts': {'$gt': ts}}, cursor_type=pymongo.CursorType.TAILABLE_AWAIT) while cursor.alive: for doc in cursor: ts = doc['ts'] print(doc) # You end up here if the find() method returns no documents, or if # no new documents are added to the collection for more than 1 second. time.sleep(1)
Para saber mais sobre cursores tailable, consulte o guia Cursores tailable no manual do MongoDB Server .
Solução de problemas
O objeto 'Cursor' não tem atributo '_Cursor__killed'
O PyMongo v3.8 ou anterior gera um TypeError
e um AttributeError
se você fornecer argumentos inválidos para o construtor Cursor
. O AttributeError
é irrelevante, mas o TypeError
contém informações de depuração, conforme mostrado no exemplo a seguir:
Exception ignored in: <function Cursor.__del__ at 0x1048129d8> ... AttributeError: 'Cursor' object has no attribute '_Cursor__killed' ... TypeError: __init__() got an unexpected keyword argument '<argument>'
Para corrigir isso, certifique-se de fornecer os argumentos de palavra-chave corretos. Você também pode atualizar para o PyMongo v3.9 ou posterior, o que remove o erro irrelevante.
"CursorNotFound ID de cursor inválido no servidor"
Os cursores no MongoDB podem atingir o tempo limite no servidor se estiverem abertos há muito tempo sem que nenhuma operação seja executada neles. Isso pode levar a uma exceção CursorNotFound
quando você tenta iterar pelo cursor.