Acceso a MongoDB con PyMongo - parte 1

Avanzado
Python
Python
Actualizado: 05/05/2026

Diagrama del tema

Conexión a MongoDB

flowchart TD
    APP["Aplicación Python"] --> CLIENT["MongoClient(URI)"]
    CLIENT --> DB["client[db_name]"]
    DB --> COLL["db[collection]"]
    COLL --> CRUD["Operaciones CRUD"]
    CRUD --> INS["insert_one / insert_many"]
    CRUD --> READ["find / find_one"]
    CRUD --> UPD["update_one / update_many ($set, $inc)"]
    CRUD --> DEL["delete_one / delete_many"]
    COLL --> TX["Transacciones (sesión multi-doc)"]

MongoDB es una base de datos NoSQL orientada a documentos que almacena datos en formato similar a JSON (BSON). Para interactuar con MongoDB desde Python, utilizaremos PyMongo, la biblioteca oficial que nos permite conectarnos y realizar operaciones con bases de datos MongoDB.

Antes de comenzar a trabajar con MongoDB, necesitamos establecer una conexión adecuada. Esta conexión será el punto de entrada para todas las operaciones que realizaremos posteriormente con la base de datos.

Instalación de PyMongo

Lo primero que necesitamos es instalar la biblioteca PyMongo. Podemos hacerlo fácilmente utilizando pip:

pip install pymongo

Para proyectos que requieren versiones específicas o entornos aislados, es recomendable usar un entorno virtual:

python -m venv venv
source venv/bin/activate  # En Windows: venv\Scripts\activate
pip install pymongo

Estableciendo una conexión básica

La forma más simple de conectarse a MongoDB es utilizando el cliente de PyMongo:

from pymongo import MongoClient

# Conexión a MongoDB local (por defecto en puerto 27017)
client = MongoClient('localhost', 27017)

# Alternativa usando URI de conexión
client = MongoClient('mongodb://localhost:27017/')

El objeto client es nuestra puerta de entrada a MongoDB y nos permitirá acceder a todas las bases de datos y colecciones disponibles en el servidor.

Conexión con autenticación

En entornos de producción, normalmente necesitaremos proporcionar credenciales de autenticación:

# Conexión con autenticación básica
client = MongoClient('mongodb://usuario:contraseña@localhost:27017/')

# Método alternativo especificando parámetros
client = MongoClient(
    host='localhost',
    port=27017,
    username='usuario',
    password='contraseña',
    authSource='admin'  # Base de datos donde se almacenan las credenciales
)

El parámetro authSource específica la base de datos donde MongoDB verifica las credenciales del usuario, generalmente es 'admin'.

Conexión a MongoDB Atlas

MongoDB Atlas es el servicio de base de datos en la nube ofrecido por MongoDB. Para conectarnos a una instancia de MongoDB Atlas:

# Conexión a MongoDB Atlas
connection_string = "mongodb+srv://usuario:contraseña@cluster0.mongodb.net/mibasededatos"
client = MongoClient(connection_string)

La cadena de conexión para Atlas sigue el formato mongodb+srv://, que incluye la resolución de DNS para encontrar los servidores del clúster.

Configuración de opciones de conexión

PyMongo permite configurar múltiples opciones para personalizar el comportamiento de la conexión:

# Conexión con opciones avanzadas
client = MongoClient(
    'mongodb://localhost:27017/',
    maxPoolSize=50,                # Tamaño máximo del pool de conexiones
    connectTimeoutMS=5000,         # Tiempo máximo para establecer conexión (ms)
    socketTimeoutMS=30000,         # Tiempo máximo para operaciones de socket (ms)
    serverSelectionTimeoutMS=5000, # Tiempo máximo para seleccionar servidor (ms)
    retryWrites=True               # Reintentar operaciones de escritura fallidas
)

Estas opciones son especialmente útiles en entornos de producción donde necesitamos controlar aspectos como el rendimiento y la resiliencia.

Accediendo a bases de datos y colecciones

Una vez establecida la conexión, podemos acceder a las bases de datos y colecciones:

# Acceder a una base de datos
db = client['mi_base_datos']  # Alternativa: db = client.mi_base_datos

# Acceder a una colección
coleccion = db['mi_coleccion']  # Alternativa: coleccion = db.mi_coleccion

En MongoDB, las bases de datos y colecciones se crean automáticamente cuando insertamos documentos, por lo que no es necesario crearlas explícitamente.

Verificación de conexión

Es una buena práctica verificar que la conexión se ha establecido correctamente:

try:
    # Intenta una operación simple para verificar la conexión
    client.admin.command('ping')
    print("Conexión establecida correctamente")
except Exception as e:
    print(f"Error de conexión: {e}")

Uso de contextos para gestionar conexiones

Python proporciona el gestor de contexto (with) que podemos utilizar para manejar conexiones de manera más segura:

from pymongo import MongoClient
from contextlib import contextmanager

@contextmanager
def get_mongo_client(uri='mongodb://localhost:27017/'):
    """Crea un cliente MongoDB y lo cierra automáticamente al finalizar."""
    client = MongoClient(uri)
    try:
        yield client
    finally:
        client.close()

# Uso del gestor de contexto
with get_mongo_client() as client:
    db = client.mi_base_datos
    # Realizar operaciones con la base de datos
    resultado = db.mi_coleccion.find_one()
    print(resultado)
# Al salir del bloque 'with', la conexión se cierra automáticamente

Este enfoque garantiza que las conexiones se cierren adecuadamente, incluso si ocurren excepciones durante la ejecución.

Conexión con URI completa

Para casos más complejos, podemos utilizar una URI completa que incluya todos los parámetros de conexión:

uri = "mongodb://usuario:contraseña@localhost:27017/mi_base_datos?retryWrites=true&w=majority&authSource=admin&ssl=true"
client = MongoClient(uri)

Los parámetros en la URI permiten configurar aspectos como:

  • retryWrites: reintentar operaciones de escritura fallidas
  • w: nivel de confirmación de escritura
  • authSource: base de datos para autenticación
  • ssl: habilitar conexión segura mediante SSL/TLS

Manejo de errores de conexión

Es importante implementar un manejo adecuado de errores para las conexiones:

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

try:
    client = MongoClient('mongodb://localhost:27017/', serverSelectionTimeoutMS=2000)
    client.admin.command('ismaster')  # Comando para verificar conexión
    print("Servidor MongoDB disponible")
except ConnectionFailure:
    print("No se pudo conectar al servidor MongoDB")
except ServerSelectionTimeoutError:
    print("Tiempo de espera agotado al intentar conectar con MongoDB")

Capturar excepciones específicas nos permite responder adecuadamente a diferentes tipos de problemas de conexión.

Conexiones con pools

Para aplicaciones con alto tráfico, PyMongo gestiona automáticamente un pool de conexiones:

# Configuración de pool de conexiones
client = MongoClient(
    'mongodb://localhost:27017/',
    maxPoolSize=100,      # Máximo de conexiones en el pool
    minPoolSize=10,       # Mínimo de conexiones mantenidas en el pool
    maxIdleTimeMS=45000   # Tiempo máximo que una conexión puede estar inactiva
)

El pool de conexiones mejora el rendimiento al reutilizar conexiones existentes en lugar de crear nuevas para cada operación.

Operaciones con documentos

Una vez establecida la conexión con MongoDB, podemos comenzar a realizar operaciones CRUD (Crear, Leer, Actualizar y Eliminar) con los documentos. En MongoDB, los datos se almacenan como documentos en formato BSON (Binary JSON), lo que permite estructuras de datos flexibles y anidadas.

Inserción de documentos

PyMongo ofrece varios métodos para insertar documentos en una colección. Podemos insertar un solo documento o múltiples documentos a la vez.

Insertar un documento único

Para insertar un único documento, utilizamos el método insert_one():

from pymongo import MongoClient

# Establecer conexión
client = MongoClient('mongodb://localhost:27017/')
db = client['tienda']
coleccion = db['productos']

# Crear un documento
producto = {
    "nombre": "Laptop",
    "marca": "TechPro",
    "precio": 1200.50,
    "stock": 10,
    "categorias": ["electrónica", "computadoras"],
    "especificaciones": {
        "procesador": "Intel i7",
        "memoria": "16GB",
        "almacenamiento": "512GB SSD"
    }
}

# Insertar el documento
resultado = coleccion.insert_one(producto)

# Obtener el ID del documento insertado
print(f"Documento insertado con ID: {resultado.inserted_id}")

El método insert_one() devuelve un objeto InsertOneResult que contiene el inserted_id, un identificador único generado automáticamente por MongoDB si no lo especificamos.

Insertar múltiples documentos

Para insertar varios documentos a la vez, utilizamos insert_many():

# Lista de documentos a insertar
productos = [
    {
        "nombre": "Monitor",
        "marca": "ViewClear",
        "precio": 350.75,
        "stock": 15,
        "categorias": ["electrónica", "periféricos"]
    },
    {
        "nombre": "Teclado",
        "marca": "TypeMaster",
        "precio": 85.99,
        "stock": 30,
        "categorias": ["periféricos", "accesorios"]
    },
    {
        "nombre": "Mouse",
        "marca": "ClickPro",
        "precio": 45.50,
        "stock": 25,
        "categorias": ["periféricos", "accesorios"]
    }
]

# Insertar múltiples documentos
resultado = coleccion.insert_many(productos)

# Obtener los IDs de los documentos insertados
print(f"Documentos insertados: {len(resultado.inserted_ids)}")
print(f"IDs: {resultado.inserted_ids}")

El método insert_many() devuelve un objeto InsertManyResult que contiene una lista de los IDs de todos los documentos insertados.

Lectura de documentos

PyMongo proporciona varios métodos para recuperar documentos de una colección.

Encontrar un documento

Para recuperar un único documento, utilizamos find_one():

# Buscar un documento por un criterio específico
producto = coleccion.find_one({"nombre": "Laptop"})

if producto:
    print(f"Producto encontrado: {producto['nombre']}, Precio: {producto['precio']}")
else:
    print("Producto no encontrado")

El método find_one() devuelve el primer documento que coincide con el criterio de búsqueda o None si no encuentra ninguno.

Encontrar múltiples documentos

Para recuperar múltiples documentos, utilizamos el método find():

# Buscar todos los productos de una categoría
cursor = coleccion.find({"categorias": "periféricos"})

# Iterar sobre los resultados
for producto in cursor:
    print(f"{producto['nombre']} - {producto['marca']} - ${producto['precio']}")

El método find() devuelve un cursor que podemos iterar para acceder a los documentos. El cursor es un objeto iterable que recupera los documentos de forma eficiente, cargándolos por lotes según sea necesario.

Filtrado y proyección

Podemos filtrar los resultados y especificar qué campos queremos recuperar:

# Buscar productos con precio menor a 100 y mostrar solo nombre y precio
cursor = coleccion.find(
    {"precio": {"$lt": 100}},  # Filtro: precio menor que 100
    {"nombre": 1, "precio": 1, "_id": 0}  # Proyección: incluir nombre y precio, excluir _id
)

for producto in cursor:
    print(f"{producto['nombre']}: ${producto['precio']}")

En la proyección, especificamos 1 para incluir un campo y 0 para excluirlo. Por defecto, el campo _id siempre se incluye a menos que lo excluyamos explícitamente.

Ordenación, límite y salto

Podemos ordenar, limitar y saltar resultados:

# Buscar productos ordenados por precio (descendente), 
# saltando los 2 primeros y limitando a 3 resultados
cursor = coleccion.find().sort("precio", -1).skip(2).limit(3)

print("Productos (ordenados por precio descendente, saltando 2, limitando a 3):")
for producto in cursor:
    print(f"{producto['nombre']}: ${producto['precio']}")
  • sort(): Ordena los resultados. Usamos 1 para orden ascendente y -1 para descendente.
  • skip(): Salta un número específico de documentos.
  • limit(): Limita el número de documentos devueltos.

Actualización de documentos

PyMongo ofrece varios métodos para actualizar documentos existentes.

Actualizar un documento

Para actualizar un único documento, utilizamos update_one():

# Actualizar el precio de un producto
resultado = coleccion.update_one(
    {"nombre": "Laptop"},  # Filtro para encontrar el documento
    {"$set": {"precio": 1299.99, "stock": 8}}  # Operación de actualización
)

print(f"Documentos encontrados: {resultado.matched_count}")
print(f"Documentos modificados: {resultado.modified_count}")

El método update_one() actualiza el primer documento que coincide con el filtro. Devuelve un objeto UpdateResult con información sobre la operación.

Actualizar múltiples documentos

Para actualizar varios documentos a la vez, utilizamos update_many():

# Aplicar un descuento del 10% a todos los productos de la categoría "periféricos"
resultado = coleccion.update_many(
    {"categorias": "periféricos"},  # Filtro
    {"$mul": {"precio": 0.9}}  # Multiplicar el precio por 0.9 (10% de descuento)
)

print(f"Documentos actualizados: {resultado.modified_count}")

El operador $mul multiplica el valor del campo por el número especificado.

Operadores de actualización

MongoDB proporciona varios operadores para realizar diferentes tipos de actualizaciones:

# Ejemplos de diferentes operadores de actualización
coleccion.update_one(
    {"nombre": "Monitor"},
    {
        "$set": {"en_oferta": True},  # Establecer un valor
        "$inc": {"stock": -2},  # Incrementar (o decrementar con valor negativo)
        "$push": {"categorias": "ofertas"},  # Añadir un elemento a un array
        "$currentDate": {"ultima_modificacion": True}  # Establecer fecha actual
    }
)

Algunos operadores comunes:

  • $set: Establece el valor de un campo
  • $inc: Incrementa el valor de un campo
  • $push: Añade un elemento a un array
  • $pull: Elimina elementos de un array
  • $currentDate: Establece el valor a la fecha actual

Upsert (actualizar o insertar)

El parámetro upsert permite crear un documento si no existe ninguno que coincida con el filtro:

# Actualizar un producto o crearlo si no existe
coleccion.update_one(
    {"nombre": "Auriculares"},
    {
        "$set": {
            "marca": "SoundMaster",
            "precio": 129.99,
            "stock": 20,
            "categorias": ["audio", "periféricos"]
        }
    },
    upsert=True  # Crear el documento si no existe
)

Eliminación de documentos

PyMongo proporciona métodos para eliminar documentos de una colección.

Eliminar un documento

Para eliminar un único documento, utilizamos delete_one():

# Eliminar un producto agotado
resultado = coleccion.delete_one({"stock": 0})

print(f"Documentos eliminados: {resultado.deleted_count}")

El método delete_one() elimina el primer documento que coincide con el filtro.

Eliminar múltiples documentos

Para eliminar varios documentos a la vez, utilizamos delete_many():

# Eliminar todos los productos descontinuados
resultado = coleccion.delete_many({"descontinuado": True})

print(f"Documentos eliminados: {resultado.deleted_count}")

Eliminar todos los documentos

Para eliminar todos los documentos de una colección:

# Eliminar todos los documentos (¡usar con precaución!)
resultado = coleccion.delete_many({})
print(f"Se eliminaron todos los documentos: {resultado.deleted_count}")

Operaciones atómicas

MongoDB permite realizar operaciones atómicas con el método find_one_and_update() y similares:

# Decrementar el stock y obtener el documento actualizado en una sola operación
producto = coleccion.find_one_and_update(
    {"nombre": "Laptop", "stock": {"$gt": 0}},  # Filtro: producto con stock > 0
    {"$inc": {"stock": -1}},  # Decrementar stock en 1
    return_document=True  # Devolver el documento después de la actualización
)

if producto:
    print(f"Producto vendido: {producto['nombre']}, Stock restante: {producto['stock']}")
else:
    print("Producto agotado o no encontrado")

Otros métodos similares:

  • find_one_and_delete(): Encuentra un documento y lo elimina
  • find_one_and_replace(): Encuentra un documento y lo reemplaza

Operaciones en masa (Bulk Operations)

Para operaciones en masa más eficientes, podemos utilizar las operaciones bulk:

from pymongo import UpdateOne, DeleteOne

# Crear una lista de operaciones
operaciones = [
    UpdateOne({"nombre": "Laptop"}, {"$inc": {"stock": 5}}),
    UpdateOne({"nombre": "Monitor"}, {"$set": {"precio": 329.99}}),
    DeleteOne({"nombre": "Producto obsoleto"})
]

# Ejecutar todas las operaciones en una sola solicitud
resultado = coleccion.bulk_write(operaciones)

print(f"Documentos insertados: {resultado.inserted_count}")
print(f"Documentos actualizados: {resultado.modified_count}")
print(f"Documentos eliminados: {resultado.deleted_count}")

Las operaciones bulk son más eficientes cuando necesitamos realizar múltiples operaciones, ya que reducen el número de viajes de ida y vuelta al servidor.

Transacciones

A partir de MongoDB 4.0, podemos utilizar transacciones para garantizar la atomicidad de múltiples operaciones:

# Iniciar una sesión
with client.start_session() as sesion:
    # Iniciar una transacción
    with sesion.start_transaction():
        # Realizar múltiples operaciones dentro de la transacción
        db.productos.update_one(
            {"_id": producto_id}, 
            {"$inc": {"stock": -1}}, 
            session=sesion
        )
        
        db.ventas.insert_one(
            {
                "producto_id": producto_id,
                "cantidad": 1,
                "fecha": datetime.now()
            }, 
            session=sesion
        )
        
        # Si llegamos aquí sin errores, la transacción se confirmará automáticamente
        # Si ocurre una excepción, la transacción se abortará

Las transacciones son especialmente útiles cuando necesitamos garantizar que un conjunto de operaciones se realice como una unidad atómica.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Python

Documentación oficial de Python
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Python es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Python

Explora más contenido relacionado con Python y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Comprender cómo establecer conexiones a MongoDB usando PyMongo, incluyendo autenticación y configuración avanzada. Realizar operaciones básicas con documentos: inserción, lectura con filtros y proyecciones. Actualizar documentos con operadores como $set, $inc y $push, y usar upsert. Eliminar documentos de forma individual o en bloque. Utilizar operaciones en masa y transacciones para garantizar atomicidad.