Overview
Para conectarte a una implementación de MongoDB, necesitas dos cosas:
Un URI de conexión, también conocido como cadena de conexión, que le indica a PyMongo a qué implementación de MongoDB debes conectarse.
Un objeto MongoClient, que crea la conexión a la implementación de MongoDB y permite realizar operaciones en ella.
También puede utilizar cualquiera de estos componentes para personalizar la forma en que PyMongo se comporta mientras está conectado a MongoDB.
Esta guía le muestra cómo crear una cadena de conexión y utilizar una MongoClient objeto para conectarse a MongoDB.
URI de conexión
Una cadena de conexión estándar incluye los siguientes componentes:
Componente | Descripción |
|---|---|
| Requerido. Un prefijo que identifica esto como un string en el formato de conexión estándar. |
| Opcional. Credenciales de autenticación. Si las incluye, el cliente autentica al usuario con la base de datos especificada en |
| Requerido. El host y el número de puerto opcional donde se ejecuta MongoDB. Si no incluyes el número de puerto, el controlador utiliza el puerto por defecto, |
| Opcional. La base de datos de autenticación que se debe usar si la cadena de conexión incluye las credenciales de autenticación |
| Opcional. Un string del query que especifica opciones específicas de conexión como pares |
Para obtener más información sobre cómo crear una cadena de conexión, consulte Cadenas de conexión en la documentación del servidor MongoDB.
MongoClient
Para crear una conexión a MongoDB, pasa un URI de conexión como un string al constructor MongoClient. En el siguiente ejemplo, el controlador utiliza un URI de conexión de muestra para conectarse a una instancia de MongoDB en el puerto 27017 de localhost:
from pymongo import MongoClient uri = "mongodb://localhost:27017/" client = MongoClient(uri)
Si se está trabajando con una aplicación asincrónica, se debe usar la clase AsyncMongoClient. El siguiente ejemplo muestra cómo crear un objeto AsyncMongoClient:
from pymongo import AsyncMongoClient uri = "mongodb://localhost:27017/" client = AsyncMongoClient(uri)
La siguiente tabla describe los parámetros posicionales que acepta el constructor MongoClient(). Todos los parámetros son opcionales.
Parameter | Descripción | ||
|---|---|---|---|
| El nombre de host, la dirección IP o la ruta del socket de dominio Unix de la implementación de MongoDB. Si la aplicación se conecta a un set de réplicas o a un clúster, se puede especificar múltiples nombres de host o direcciones IP en una lista de Python. Si pasas una dirección IPv6 literal, debes encerrar la dirección entre corchetes ( PyMongo no admite direcciones multiconectadas ni Round-Robin DNS. Tipo de dato: | ||
| El número de puerto en el que se ejecuta MongoDB Server. Puedes incluir el número de puerto en el argumento Tipo de dato: | ||
| La clase por defecto que utiliza el cliente para decodificar documentos BSON devueltos por los queries. Este parámetro acepta los siguientes tipos:
Tipo de dato: | ||
| Si este parámetro es Para obtener más información sobre los valores de Tipo de dato: | ||
| Si este parámetro es Si su aplicación se ejecuta en un entorno function-as-a-service (FaaS), el valor por defecto es Tipo de dato: | ||
| Una instancia de la clase Tipo de dato: TypeRegistry |
También puede pasar argumentos de palabras clave al constructor MongoClient() para especificar parámetros opcionales. Para una lista completa de argumentos de palabras clave, consulte la clase MongoClient en la documentación de la API.
Ejecución concurrente
Las siguientes secciones describen el soporte de PyMongo para mecanismos de ejecución concurrente.
Multihilo
PyMongo es seguro para subprocesos y proporciona una funcionalidad incorporada de agrupamiento de conexiones para aplicaciones con subprocesos. Debido a que cada objeto MongoClient representa un grupo de conexiones a la base de datos, la mayoría de las aplicaciones requiere solo una única instancia de MongoClient, incluso a través de múltiples solicitudes.
Múltiples bifurcaciones
PyMongo brinda soporte para ejecutar el método fork() para crear un nuevo proceso. Sin embargo, si realizas la bifurcación de un proceso, debes crear una nueva instancia MongoClient en el proceso hijo.
Importante
No pases un MongoClient a un proceso hijo
Si utilizas el método fork() para crear un nuevo proceso, no pases una instancia de la clase MongoClient del proceso padre al proceso hijo. Esto crea una alta probabilidad de interbloqueo entre las instanciasMongoClient en el proceso hijo. PyMongo intenta emitir una advertencia si este interbloqueo pudiera ocurrir.
Para obtener más información sobre el interbloqueo en procesos bifurcados, consulta La bifurcación de un proceso causa un interbloqueo.
Multiprocesamiento
PyMongo brinda soporte para el módulo de Python multiprocessing. Sin embargo, en los sistemas Unix, el módulo de multiprocesamiento genera procesos utilizando el método fork(). Esto conlleva los mismos riesgos descritos en Múltiples bifurcaciones.
Para usar multiprocesamiento con PyMongo, guarda un código similar al siguiente ejemplo:
# Each process creates its own instance of MongoClient. def func(): db = pymongo.MongoClient().mydb # Do something with db. proc = multiprocessing.Process(target=func) proc.start()
Importante
No copies una instancia de la clase MongoClient del proceso padre a un proceso hijo.
Sugerencias de tipo
Si la aplicación usa Python 3.5 o posterior, se pueden agregar anotaciones de tipo, como se describe en PEP 484, al código. Las anotaciones de tipo indican los tipos de datos de las variables, los parámetros y los valores de retorno de las funciones, así como la estructura de los documentos. Algunos IDE pueden usar sugerencias de tipo para verificar el código en busca de errores de tipo y sugerir opciones adecuadas para la finalización del código.
Para usar sugerencias de tipo en su aplicación PyMongo, debe agregar una anotación de tipo a su objeto MongoClient, como se muestra en el siguiente ejemplo. Seleccione el Synchronous
o pestaña Asynchronous para ver el código correspondiente:
from pymongo import MongoClient client: MongoClient = MongoClient()
from pymongo import AsyncMongoClient client: AsyncMongoClient = AsyncMongoClient()
Para obtener información más precisa sobre el tipo, se puede incluir el tipo de documento genérico Dict[str, Any] en la anotación de tipo. Este tipo de datos coincide con todos los documentos en MongoDB. El siguiente ejemplo muestra cómo incluir este tipo de datos en la anotación de tipo. Se debe seleccionar la pestaña Synchronous o Asynchronous para ver el código correspondiente:
from pymongo import MongoClient from typing import Any, Dict client: MongoClient[Dict[str, Any]] = MongoClient()
from pymongo import AsyncMongoClient from typing import Any, Dict client: AsyncMongoClient[Dict[str, Any]] = AsyncMongoClient()
Si todos los documentos con los que se trabaja corresponden a un único tipo personalizado, se puede especificar el tipo personalizado como una sugerencia de tipo para el objeto MongoClient. Esto proporciona información de tipo más precisa que el tipo genérico Dict[str, Any].
El siguiente ejemplo muestra cómo especificar el tipo Movie como una sugerencia de tipo para un objeto MongoClient. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
from typing import TypedDict class Movie(TypedDict): name: str year: int client: MongoClient[Movie] = MongoClient()
from typing import TypedDict class Movie(TypedDict): name: str year: int client: AsyncMongoClient[Movie] = AsyncMongoClient()
Cerrar un MongoClient
Durante la recolección de basura, PyMongo limpia automáticamente los recursos del lado de la aplicación utilizados por una instancia MongoClient. Sin embargo, PyMongo no garantiza el cierre de los recursos del lado del servidor, como las sesiones o cursores abiertos. Se puede garantizar que PyMongo cierre estos recursos mediante el método close() en la instancia MongoClient cuando finalice el uso, como se muestra en el siguiente ejemplo:
client.close()
También puedes instanciar al cliente en una instrucción with, como se muestra en el siguiente ejemplo. El cliente se cierra automáticamente cuando el bloque termina.
with MongoClient("mongodb://localhost:27017/") as client: db = client.get_database("mydatabase") # Perform further client operations here
Solución de problemas
MongoClient falla al ConfigurationError
Proporcionar nombres de argumentos de palabras clave no válidos hace que el controlador genere este error.
Asegúrate de que los argumentos de palabra clave que especifiques existan y estén escritos correctamente.
La bifurcación de un proceso causa un interbloqueo.
Una instancia MongoClient genera múltiples hilos para ejecutar tareas en segundo plano, como la supervisión de servidores conectados. Estos hilos comparten un estado que está protegido por instancias de la clase threading.Lock, que en sí mismas no son seguras para bifurcación. PyMongo está sujeto a las mismas limitaciones que cualquier otro código multihilo que utilice la clase threading.Lock o cualquier exclusión mutua.
Una de estas limitaciones es que los bloqueos se vuelven inútiles después de ejecutar el método fork(). Cuando fork() se ejecuta, el controlador copia todos los bloqueos del proceso padre al proceso hijo en el mismo estado en que estaban en el proceso padre. Si están bloqueados en el proceso padre, también estarán bloqueados en el proceso hijo. El proceso hijo creado por fork() tiene solo un hilo, por lo que cualquier bloqueo creado por otros hilos en el proceso padre nunca se libera en el proceso hijo. La próxima vez que el proceso hijo intente adquirir uno de estos bloqueos, se producirá un interbloqueo.
A partir de la versión de PyMongo,4.3 tras llamar al os.fork() método, el controlador usa el os.register_at_fork() método para restablecer sus bloqueos y otros estados compartidos en el proceso hijo. Si bien esto reduce la probabilidad de un interbloqueo, PyMongo depende de bibliotecas que no son seguras para bifurcaciones en aplicaciones multihilo, como OpenSSL y getaddrinfo().3 Por lo tanto, aún puede producirse un interbloqueo.
La página del manual de Linux para fork(2) también impone la siguiente restricción:
Después de un
fork()en un programa multihilo, el proceso hijo solo puede ejecutar con seguridad funciones seguras para señales asíncronas (consulta signal-safety(7)) hasta que ejecute execve(2).
Debido a que PyMongo se basa en funciones que no son seguras para señales asíncronas, puede causar interbloqueos o fallos cuando se ejecuta en un proceso hijo.
Tip
Para un ejemplo de un interbloqueo en un proceso hijo, consulta PYTHON-3406 en Jira.
Para obtener más información sobre los problemas causados por los bloqueos de Python en contextos multihilo con fork(), consulta Problema 6721 en el Seguimiento de problemas de Python.
Anotaciones de tipo de cliente
Si no se agrega una anotación de tipo para el objeto MongoClient, el verificador de tipos podría mostrar un error similar al siguiente:
from pymongo import MongoClient client = MongoClient() # error: Need type annotation for "client"
La solución es anotar el objeto MongoClient como client: MongoClient o client: MongoClient[Dict[str, Any]].
Tipo incompatible
Si especifica MongoClient como una sugerencia de tipo, pero no incluye los tipos de datos para el documento, las claves y los valores, su verificador de tipos podría mostrar un error similar al siguiente:
error: Dict entry 0 has incompatible type "str": "int"; expected "Mapping[str, Any]": "int"
La solución es agregar la siguiente sugerencia de tipo al objeto MongoClient:
client: MongoClient[Dict[str, Any]]
Documentación de la API
Para aprender más sobre cómo crear un objeto MongoClient en PyMongo, consulta la siguiente documentación de API: