W3docs

MongoDB Insert

Aprenda a inserir documentos únicos e múltiplos no MongoDB com Python e o driver pymongo — com tratamento de erros, ObjectId e inserção em lote.

O MongoDB armazena dados como documentos — objetos flexíveis semelhantes a JSON que podem conter campos aninhados e arrays. Este capítulo mostra como inserir um documento de cada vez com insert_one(), inserir vários documentos em uma única chamada com insert_many(), entender o campo _id gerado automaticamente, tratar erros de chave duplicada e escolher entre inserções em lote ordenadas e não ordenadas.

Pré-requisitos

pip install pymongo

Conectando ao MongoDB

Importe MongoClient e abra uma conexão antes de realizar qualquer operação de inserção. Quando o MongoDB estiver em execução localmente com as configurações padrão, você pode chamar MongoClient() sem argumentos:

from pymongo import MongoClient

client = MongoClient()          # connects to localhost:27017
db = client["bookstore"]        # database (created on first write)
books = db["books"]             # collection (created on first write)

Para conectar a um servidor remoto ou ao Atlas, passe uma URI de conexão:

client = MongoClient("mongodb://username:password@hostname:27017/")

MongoClient mantém um pool de conexões internamente, portanto você deve criar um cliente por aplicação e reutilizá-lo em todas as operações.

Inserindo um Único Documento com insert_one()

insert_one() adiciona um documento a uma coleção e retorna um objeto InsertOneResult. A propriedade mais útil desse objeto é inserted_id, que contém o _id atribuído ao novo documento.

from pymongo import MongoClient

client = MongoClient()
books = client["bookstore"]["books"]

document = {
    "title": "The Pragmatic Programmer",
    "author": "David Thomas",
    "year": 1999,
    "in_stock": True,
}

result = books.insert_one(document)
print("Inserted _id:", result.inserted_id)

Exemplo de saída:

Inserted _id: 64b3e2c1f0a1234567890abc

O valor exato de _id será diferente a cada vez — o MongoDB gera um ObjectId único a menos que você forneça o seu próprio _id.

Entendendo o Campo _id

Todo documento MongoDB deve ter um campo _id. Se você não incluir um, o driver gera automaticamente um valor bson.ObjectId. O ObjectId é um valor de 12 bytes que codifica:

  • um timestamp Unix de 4 bytes (segundos),
  • um valor aleatório de 5 bytes exclusivo para a máquina e o processo,
  • um contador incremental de 3 bytes.

Isso significa que os valores de ObjectId são aproximadamente ordenados cronologicamente e globalmente únicos sem nenhuma coordenação entre servidores.

Você pode fornecer seu próprio _id se tiver uma chave única natural (por exemplo, um ISBN):

result = books.insert_one({
    "_id": "978-0-13-468599-1",
    "title": "The Pragmatic Programmer",
    "author": "David Thomas",
    "year": 1999,
})
print("Inserted _id:", result.inserted_id)
# Inserted _id: 978-0-13-468599-1

Se você inserir um segundo documento com o mesmo _id, o MongoDB lança um DuplicateKeyError (consulte Tratando Erros abaixo).

Inserindo Vários Documentos com insert_many()

insert_many() aceita uma lista de documentos e os insere todos em uma única viagem de rede. Ele retorna um InsertManyResult cujo atributo inserted_ids contém a lista de valores _id atribuídos na ordem de inserção.

from pymongo import MongoClient

client = MongoClient()
books = client["bookstore"]["books"]

new_books = [
    {"title": "Clean Code", "author": "Robert C. Martin", "year": 2008},
    {"title": "Refactoring",  "author": "Martin Fowler",    "year": 1999},
    {"title": "Design Patterns", "author": "Gang of Four",  "year": 1994},
]

result = books.insert_many(new_books)
print("Inserted IDs:", result.inserted_ids)

Exemplo de saída:

Inserted IDs: [ObjectId('...'), ObjectId('...'), ObjectId('...')]

Inserções Ordenadas vs. Não Ordenadas

Por padrão, insert_many() usa o modo ordenado: os documentos são inseridos um a um na ordem da lista, e o processamento para no primeiro erro.

Passe ordered=False para o modo não ordenado: o MongoDB tenta cada documento de forma independente e coleta todos os erros antes de lançar uma exceção. Isso é mais rápido para grandes lotes onde você espera algumas duplicatas e deseja ignorar documentos inválidos em vez de abortar todo o lote.

from pymongo import MongoClient
from pymongo.errors import BulkWriteError

client = MongoClient()
books = client["bookstore"]["books"]

# Two documents with duplicate _id values mixed in
docs = [
    {"_id": 1, "title": "Book A"},
    {"_id": 2, "title": "Book B"},
    {"_id": 1, "title": "Duplicate — will fail"},  # duplicate _id
    {"_id": 3, "title": "Book C"},
]

try:
    result = books.insert_many(docs, ordered=False)
    print("Inserted:", result.inserted_ids)
except BulkWriteError as e:
    # inserted_ids still shows the documents that succeeded
    print("Some inserts failed:", e.details["nInserted"], "succeeded")
    for err in e.details["writeErrors"]:
        print("  Error on index", err["index"], "—", err["errmsg"])

Com ordered=False, Book A, Book B e Book C são inseridos mesmo que a duplicata falhe. Com ordered=True (padrão), o processamento pararia no terceiro documento e Book C nunca seria inserido.

Tratando Erros

Erro de Chave Duplicada

Inserir um documento cujo _id (ou qualquer campo coberto por um índice único) já existe lança pymongo.errors.DuplicateKeyError:

from pymongo import MongoClient
from pymongo.errors import DuplicateKeyError

client = MongoClient()
books = client["bookstore"]["books"]

try:
    books.insert_one({"_id": "isbn-001", "title": "First"})
    books.insert_one({"_id": "isbn-001", "title": "Duplicate"})  # raises
except DuplicateKeyError as e:
    print("Duplicate key:", e.details["keyValue"])

Saída:

Duplicate key: {'_id': 'isbn-001'}

Erros de Conexão

MongoClient() tem sucesso mesmo quando o MongoDB não está em execução — o erro só aparece quando você faz uma solicitação real. Envolva as operações de inserção em um try/except para tratar falhas de conexão de forma elegante:

from pymongo import MongoClient
from pymongo.errors import ConnectionFailure, PyMongoError

client = MongoClient(serverSelectionTimeoutMS=3000)

try:
    result = books.insert_one({"title": "Test"})
    print("Inserted:", result.inserted_id)
except ConnectionFailure:
    print("Could not reach MongoDB server.")
except PyMongoError as e:
    print("MongoDB error:", e)

Verificando o Resultado

Tanto insert_one() quanto insert_many() retornam objetos de resultado com propriedades úteis:

Objeto de resultadoPropriedades principais
InsertOneResultinserted_id, acknowledged
InsertManyResultinserted_ids (lista), acknowledged

acknowledged é True quando o MongoDB confirmou a escrita. Pode ser False somente quando você usa um nível de escrita não reconhecida (w=0), que ignora a confirmação para máxima velocidade ao custo de não saber se a escrita foi bem-sucedida.

Exemplo Completo Funcional

O script autocontido a seguir conecta a um servidor MongoDB local, insere vários documentos e imprime os resultados:

from pymongo import MongoClient
from pymongo.errors import DuplicateKeyError, BulkWriteError

DB_NAME = "demo_bookstore"
COL_NAME = "books"

def main():
    client = MongoClient(serverSelectionTimeoutMS=3000)

    # Verify connectivity
    client.admin.command("ping")
    print("Connected to MongoDB")

    col = client[DB_NAME][COL_NAME]
    col.drop()  # start fresh for this demo

    # --- insert_one ---
    result = col.insert_one({
        "_id": "isbn-001",
        "title": "The Pragmatic Programmer",
        "author": "David Thomas",
        "year": 1999,
    })
    print("insert_one _id:", result.inserted_id)

    # --- insert_many ---
    result = col.insert_many([
        {"title": "Clean Code",      "author": "Robert C. Martin", "year": 2008},
        {"title": "Refactoring",     "author": "Martin Fowler",    "year": 1999},
        {"title": "Design Patterns", "author": "Gang of Four",     "year": 1994},
    ])
    print("insert_many IDs:", result.inserted_ids)

    # --- duplicate key ---
    try:
        col.insert_one({"_id": "isbn-001", "title": "Duplicate"})
    except DuplicateKeyError:
        print("Caught DuplicateKeyError as expected")

    # --- unordered bulk insert ---
    docs = [
        {"_id": "isbn-002", "title": "Book A"},
        {"_id": "isbn-001", "title": "Dup — will fail"},  # duplicate
        {"_id": "isbn-003", "title": "Book C"},
    ]
    try:
        col.insert_many(docs, ordered=False)
    except BulkWriteError as e:
        print("Bulk insert: succeeded =", e.details["nInserted"],
              ", failed =", len(e.details["writeErrors"]))

    print("Total documents:", col.count_documents({}))

    # Clean up
    client.drop_database(DB_NAME)

if __name__ == "__main__":
    main()

Saída esperada:

Connected to MongoDB
insert_one _id: isbn-001
insert_many IDs: [ObjectId('...'), ObjectId('...'), ObjectId('...')]
Caught DuplicateKeyError as expected
Bulk insert: succeeded = 2 , failed = 1
Total documents: 6

Erros Comuns

PyMongo modifica seu documento

Quando você passa um dict simples para insert_one(), o PyMongo adiciona uma chave _id ao dict original:

doc = {"title": "My Book"}
col.insert_one(doc)
print(doc)  # {'title': 'My Book', '_id': ObjectId('...')}

Se você planeja reutilizar o mesmo dict (por exemplo, em um loop), passe uma cópia: col.insert_one(doc.copy()).

Inserções grandes: use insert_many() e não um loop

Inserir 10.000 documentos um a um realiza 10.000 viagens de rede. Use insert_many() para enviá-los todos de uma vez — é ordens de magnitude mais rápido para cargas em lote.

Se sua lista for muito grande (milhões de documentos), divida-a em lotes de alguns milhares para evitar exceder o limite de tamanho de documento BSON de 48 MB por lote.

Campos de data precisam de objetos datetime, não strings

O MongoDB armazena datas como BSON Date (milissegundos desde a época). Use datetime.datetime do Python para campos de data para que sejam armazenados e consultados corretamente:

from datetime import datetime
col.insert_one({"title": "New Book", "published": datetime(2024, 3, 15)})

Próximos Passos

  • MongoDB Find — consulte e filtre os documentos que você acabou de inserir.
  • MongoDB Update — modifique documentos existentes.
  • MongoDB Delete — remova documentos de uma coleção.
  • MongoDB Query — use operadores de comparação e lógicos para filtrar resultados.
Was this page helpful?