Menu Docs
Página inicial do Docs
/ / /
Driver Pymongo
/

Operações de gravação em massa

Considere um cenário no qual você deseja inserir um documento em uma coleção, atualizar vários outros documentos e excluir um documento. Se você usar métodos individuais, cada operação exigirá sua própria chamada de banco de dados. Este guia mostra como usar operações de gravação em massa para executar várias operações de gravação em uma única chamada de banco de dados.

Os exemplos neste guia usam a collection sample_restaurants.restaurants dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de amostra, consulte o tutorial Introdução ao PyMongo .

Para cada operação de gravação que você deseja executar, crie uma instância de uma das seguintes classes de operação:

  • InsertOne

  • UpdateOne

  • UpdateMany

  • ReplaceOne

  • DeleteOne

  • DeleteMany

Em seguida, passe uma lista dessas instâncias para o método bulk_write() .

As seções seguintes mostram como criar e utilizar instâncias das classes anteriores.

Para executar uma operação de inserção, crie uma instância de InsertOne e especifique o documento que você deseja inserir.

O exemplo a seguir cria uma instância de InsertOne:

operation = pymongo.InsertOne(
{
"name": "Mongo's Deli",
"cuisine": "Sandwiches",
"borough": "Manhattan",
"restaurant_id": "1234"
}
)

Você também pode criar uma instância de InsertOne passando uma instância de uma classe personalizada para o construtor. Isso oferece segurança adicional de tipo se você estiver usando uma ferramenta de verificação de tipo. A instância pela qual você passa deve herdar da classe TypedDict.

Observação

TypedDict no Python 3.7 e anteriores

A classe TypedDict está no módulo typing, que está disponível somente no Python 3.8 e posterior. Para usar a classe TypedDict em versões anteriores do Python, instale o pacote digitando_extensões.

O exemplo a seguir constrói uma instância InsertOne usando uma classe personalizada para maior segurança de tipo:

class Restaurant (TypedDict):
name: str
cuisine: str
borough: str
restaurant_id: str
operation = pymongo.InsertOne(Restaurant(
name="Mongo's Deli", cuisine="Sandwiches", borough="Manhattan", restaurant_id="1234"))

Para inserir vários documentos, crie uma instância de InsertOne para cada documento.

Observação

O campo _id deve ser único

Em uma coleção MongoDB , cada documento deve conter um campo _id com um valor único.

Se você especificar um valor para o campo _id, você deverá garantir que o valor seja único na coleção. Se você não especificar um valor, o driver gerará automaticamente um valor ObjectId exclusivo para o campo.

Recomendamos deixar o driver gerar automaticamente valores de _id para garantir exclusividade. Os valores duplicados de _id violam restrições de índice único , o que faz com que o driver retorne um erro.

Para atualizar um documento, crie uma instância de UpdateOne e passe os seguintes argumentos:

  • Um filtro de query que especifica os critérios usados para corresponder aos documentos em sua coleção

  • A operação de atualização que você deseja executar. Para obter mais informações sobre operações de atualização, consulte o guia Operadores de atualização de campo no manual do MongoDB Server .

UpdateOne atualiza o primeiro documento que corresponde ao seu filtro de query.

O exemplo a seguir cria uma instância de UpdateOne:

operation = pymongo.UpdateOne(
{ "name": "Mongo's Deli" },
{ "$set": { "cuisine": "Sandwiches and Salads" }},
)

Para atualizar vários documentos, crie uma instância de UpdateMany e passe os mesmos argumentos. UpdateMany atualiza todos os documentos que correspondem ao seu filtro de query.

O exemplo a seguir cria uma instância de UpdateMany:

operation = pymongo.UpdateMany(
{ "name": "Mongo's Deli" },
{ "$set": { "cuisine": "Sandwiches and Salads" }},
)

Uma operação de substituição remove todos os campos e valores de um documento especificado e os substitui por novos. Para executar uma operação de substituição, crie uma instância de ReplaceOne e passe um filtro de query e os campos e valores que você deseja armazenar no documento correspondente.

O exemplo a seguir cria uma instância de ReplaceOne:

operation = pymongo.ReplaceOne(
{ "restaurant_id": "1234" },
{
"name": "Mongo's Pizza",
"cuisine": "Pizza",
"borough": "Brooklyn",
"restaurant_id": "5678"
}
)

Você também pode criar uma instância de ReplaceOne passando uma instância de uma classe personalizada para o construtor. Isso oferece segurança adicional de tipo se você estiver usando uma ferramenta de verificação de tipo. A instância pela qual você passa deve herdar da classe TypedDict.

Observação

TypedDict no Python 3.7 e anteriores

A classe TypedDict está no módulo typing, que está disponível somente no Python 3.8 e posterior. Para usar a classe TypedDict em versões anteriores do Python, instale o pacote digitando_extensões.

O exemplo a seguir constrói uma instância ReplaceOne usando uma classe personalizada para maior segurança de tipo:

class Restaurant (TypedDict):
name: str
cuisine: str
borough: str
restaurant_id: str
operation = pymongo.ReplaceOne(
{ "restaurant_id": "1234" },
Restaurant(name="Mongo's Pizza", cuisine="Pizza", borough="Brooklyn", restaurant_id="5678")
)

Para substituir vários documentos, você deve criar uma instância de ReplaceOne para cada documento.

Dica

Ferramentas de verificação de tipo

Para saber mais sobre as ferramentas de verificação de tipo disponíveis para Python, consulte Verificadores de tipo na página Ferramentas.

Para excluir um documento, crie uma instância do DeleteOne e passe um filtro de query especificando o documento que você deseja excluir. DeleteOne remove somente o primeiro documento que corresponde ao seu filtro de query.

O exemplo a seguir cria uma instância de DeleteOne:

operation = pymongo.DeleteOne({ "restaurant_id": "5678" })

Para excluir vários documentos, crie uma instância do DeleteMany e passe um filtro de query especificando o documento que você deseja excluir. DeleteMany remove todos os documentos que correspondem ao seu filtro de query.

O exemplo a seguir cria uma instância de DeleteMany:

operation = pymongo.DeleteMany({ "name": "Mongo's Deli" })

Depois de definir uma instância de classe para cada operação que deseja executar, passe uma lista dessas instâncias para o método bulk_write() . Por padrão, o método executa as operações na ordem em que foram definidas na lista.

O exemplo a seguir executa diversas operações de gravação usando o método bulk_write() :

operations = [
pymongo.InsertOne(
{
"name": "Mongo's Deli",
"cuisine": "Sandwiches",
"borough": "Manhattan",
"restaurant_id": "1234"
}
),
pymongo.InsertOne(
{
"name": "Mongo's Deli",
"cuisine": "Sandwiches",
"borough": "Brooklyn",
"restaurant_id": "5678"
}
),
pymongo.UpdateMany(
{ "name": "Mongo's Deli" },
{ "$set": { "cuisine": "Sandwiches and Salads" }},
),
pymongo.DeleteOne(
{ "restaurant_id": "1234" }
)
]
results = restaurants.bulk_write(operations)
print(results)
BulkWriteResult({'writeErrors': [], 'writeConcernErrors': [], 'nInserted': 2, 'nUpserted': 0, 'nMatched': 2, 'nModified': 2, 'nRemoved': 1, 'upserted': []}, acknowledged=True)

Se qualquer uma das operações de gravação falhar, o PyMongo gerará um BulkWriteError e não executará mais nenhuma operação. BulkWriteError fornece um atributo details que inclui a operação que falhou e detalhes sobre a exceção.

Observação

Quando o PyMongo executa uma operação em massa, ele usa o write_concern da collection na qual a operação está sendo executada. O driver relata todos os erros de preocupação de gravação depois de tentar todas as operações, independentemente da ordem de execução.

Opcionalmente, o método bulk_write() aceita parâmetros adicionais, que representam opções que você pode usar para configurar a operação de gravação em massa. Se você não especificar nenhuma opção adicional, o driver não personalizará a operação de gravação em massa.

Propriedade
Descrição

ordered

If True, the driver performs the write operations in the order provided. If an error occurs, the remaining operations are not attempted.

If False, the driver performs the operations in an arbitrary order and attempts to perform all operations.
Defaults to True.

bypass_document_validation

Specifies whether the operation bypasses document-level validation. For more information, see Schema Validation in the MongoDB Server manual.
Defaults to False.

session

An instance of ClientSession. For more information, see the API documentation.

comment

A comment to attach to the operation. For more information, see the delete command fields guide in the MongoDB Server manual.

let

A map of parameter names and values. Values must be constant or closed expressions that don't reference document fields. For more information, see the let statement in the MongoDB Server manual.

O exemplo seguinte chama o método bulk_write() do exemplo anterior, com a opção ordered definida como False:

results = restaurants.bulk_write(operations, ordered=False)

Se qualquer uma das operações de gravação em uma gravação em massa não ordenada falhar, o PyMongo relatará os erros somente depois de tentar todas as operações.

Observação

Operações em massa não ordenadas não garantem ordem de execução. A ordem pode ser diferente da forma como você os lista para otimizar o tempo de execução.

O método bulk_write() retorna um objeto BulkWriteResult . O objeto BulkWriteResult contém as seguintes propriedades:

Propriedade
Descrição

acknowledged

Indicates if the server acknowledged the write operation.

bulk_api_result

The raw bulk API result returned by the server.

deleted_count

The number of documents deleted, if any.

inserted_count

The number of documents inserted, if any.

matched_count

The number of documents matched for an update, if applicable.

modified_count

The number of documents modified, if any.

upserted_count

The number of documents upserted, if any.

upserted_ids

A map of the operation's index to the _id of the upserted documents, if applicable.

Se você não adicionar uma anotação de tipo para seu objeto MongoClient, seu verificador de tipo poderá mostrar um erro semelhante ao seguinte:

from pymongo import MongoClient
client = MongoClient() # error: Need type annotation for "client"

A solução é anotar o objeto MongoClient como client: MongoClient ou client: MongoClient[Dict[str, Any]].

Se você especificar MongoClient como uma dica de tipo, mas não incluir tipos de dados para o documento, as chaves e os valores, seu verificador de tipo poderá mostrar um erro semelhante ao seguinte:

error: Dict entry 0 has incompatible type "str": "int";
expected "Mapping[str, Any]": "int"

A solução é adicionar a seguinte dica de tipo ao seu objeto MongoClient :

client: MongoClient[Dict[str, Any]]

Para saber como realizar operações de escrita individuais, consulte os seguintes guias:

Para saber mais sobre qualquer um dos métodos ou tipos discutidos neste guia, consulte a seguinte documentação da API:

Voltar

Exclua documentos

Nesta página