Overview
En esta guía, aprenderá a almacenar y recuperar archivos grandes en MongoDB usando GridFS. GridFS es una especificación implementada por PyMongo que describe cómo dividir archivos en fragmentos al almacenarlos y reensamblarlos al recuperarlos. La implementación de GridFS en el controlador es una abstracción que gestiona las operaciones y la organización del almacenamiento de archivos.
Debe usar GridFS si el tamaño de sus archivos supera el límite de tamaño de documento BSON de 16MB. Para obtener información más detallada sobre si GridFS es adecuado para su caso de uso, consulte GridFS en el manual del servidor MongoDB.
Las siguientes secciones describen las operaciones de GridFS y cómo realizarlas.
Cómo funciona GridFS
GridFS organiza los archivos en un bucket, un grupo de colecciones de MongoDB que contiene los fragmentos de archivos y la información que los describe. El bucket contiene las siguientes colecciones, nombradas según la convención definida en la especificación de GridFS:
El
chunksLa colección almacena los fragmentos de archivos binarios.La colección
filesalmacena los metadatos del archivo.
Cuando crees un nuevo bucket GridFS, el driver creará las colecciones anteriores, prefijadas con el nombre de bucket por defecto fs, a menos que indiques un nombre diferente. El controlador también crea un índice en cada colección para asegurar la recuperación eficiente de los archivos y metadatos relacionados. El driver crea el cubo GridFS, si no existe, solo cuando se realiza la primera operación de guardado. El controlador crea índices solo si no existen y cuando el cubo está vacío. Para más información sobre los índices de GridFS, consulta Índices GridFS en el manual de MongoDB Server.
Al almacenar archivos con GridFS, el controlador divide los archivos en fragmentos más pequeños, cada uno representado por un documento independiente en la colección chunks. También crea un documento en la colección files que contiene el ID, el nombre y otros metadatos del archivo. Puede cargar el archivo desde la memoria o desde un flujo de datos. Consulte el siguiente diagrama para ver cómo GridFS divide los archivos al cargarlos en un bucket.

Al recuperar archivos, GridFS obtiene los metadatos de la colección files en el depósito especificado y utiliza la información para reconstruir el archivo a partir de los documentos de la colección chunks. Puede leer el archivo en memoria o exportarlo a una secuencia.
Crear un bucket de GridFS
Para almacenar o recuperar archivos de GridFS, cree un contenedor GridFS llamando al constructor GridFSBucket() y pasando una instancia Database. Puede usar la instancia GridFSBucket para ejecutar operaciones de lectura y escritura en los archivos de su contenedor. Si trabaja con una aplicación asíncrona, utilice el constructor AsyncGridFSBucket().
Seleccione el Synchronous o pestaña Asynchronous para ver el código correspondiente:
client = MongoClient("<connection string>") db = client["db"] bucket = gridfs.GridFSBucket(db)
client = AsyncMongoClient("<connection string>") db = client["db"] bucket = gridfs.AsyncGridFSBucket(db)
Para crear o referenciar un bucket con un nombre personalizado distinto del predeterminado fs, pase el nombre del bucket como segundo parámetro al constructor GridFSBucket(), como se muestra en el siguiente ejemplo. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
custom_bucket = gridfs.GridFSBucket(db, bucket_name="myCustomBucket")
custom_bucket = gridfs.AsyncGridFSBucket(db, bucket_name="myCustomBucket")
Cargar archivos
Utilice el método open_upload_stream() de la clase GridFSBucket para crear un flujo de carga para un nombre de archivo determinado. El método open_upload_stream() permite especificar información de configuración, como el tamaño del fragmento de archivo y otros pares campo-valor que se almacenarán como metadatos. Establezca estas opciones como parámetros de open_upload_stream(), como se muestra en el siguiente ejemplo de código. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
with bucket.open_upload_stream( "my_file", chunk_size_bytes=1048576, metadata={"contentType": "text/plain"} ) as grid_in: grid_in.write("data to store")
async with bucket.open_upload_stream( "my_file", chunk_size_bytes=1048576, metadata={"contentType": "text/plain"} ) as grid_in: await grid_in.write("data to store")
Recuperar información del archivo
En esta sección, puedes aprender a recuperar metadatos de archivos almacenados en la colección files del depósito de GridFS. Los metadatos contienen información sobre el archivo al que se refieren, incluyendo:
El
_iddel archivoEl nombre del archivo
La longitud/tamaño del archivo
La fecha y hora de carga
Un documento
metadataen el que puedes almacenar cualquier otra información
Para recuperar archivos de un bucket de GridFS, llame al método find() en la instancia GridFSBucket. El método devuelve una instancia Cursor desde la que puede acceder a los resultados. Para obtener más información sobre los objetos Cursor en PyMongo, consulte Acceder a datos desde un cursor.
El siguiente ejemplo de código muestra cómo recuperar e imprimir metadatos de todos los archivos de un bucket de GridFS. Utiliza la sintaxis for...in para recorrer el iterable Cursor y mostrar los resultados. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
for file_doc in bucket.find({}): print(file_doc)
async for file_doc in bucket.find({}): print(file_doc)
El find() método acepta varias especificaciones de consulta. Puede usar sus parámetros para especificar el orden de clasificación, el número máximo de documentos a devolver y el número de documentos que se omitirán antes de devolver. Para obtener más información sobre las consultas en MongoDB, consulte Buscar documentos.
Descarga de archivos
Puede descargar archivos de su base de datos MongoDB utilizando el método open_download_stream_by_name() de GridFSBucket para crear un flujo de descarga.
El siguiente ejemplo muestra cómo descargar un archivo referenciado por el nombre "my_file" y leer su contenido. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
file = bucket.open_download_stream_by_name("my_file") contents = file.read()
file = await bucket.open_download_stream_by_name("my_file") contents = await file.read()
Nota
Si hay varios documentos con el mismo valor filename, GridFS transmitirá el archivo más reciente con el nombre dado (según lo determinado por el campo uploadDate).
Como alternativa, puede usar el método open_download_stream(), que toma el campo _id de un archivo como parámetro. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
file = bucket.open_download_stream(ObjectId("66b3c86e672a17b6c8a4a4a9")) contents = file.read()
file = await bucket.open_download_stream(ObjectId("66b3c86e672a17b6c8a4a4a9")) contents = await file.read()
Nota
La API de streaming de GridFS no puede cargar fragmentos parciales. Cuando un flujo de descarga necesita extraer un fragmento de MongoDB, lo extrae completo a memoria. El tamaño predeterminado de fragmento de 255kilobytes suele ser suficiente, pero se puede reducir para reducir la sobrecarga de memoria.
Cambiar nombre de archivos
Utilice el método rename() para actualizar el nombre de un archivo GridFS en su bucket. Debe especificar el archivo que desea renombrar por su campo _id, no por su nombre.
El siguiente ejemplo muestra cómo actualizar el campo filename a "new_file_name" haciendo referencia al campo _id de un documento. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
bucket.rename(ObjectId("66b3c86e672a17b6c8a4a4a9"), "new_file_name")
await bucket.rename(ObjectId("66b3c86e672a17b6c8a4a4a9"), "new_file_name")
Nota
El método rename() solo permite actualizar el nombre de un archivo a la vez. Para renombrar varios archivos, recupere del depósito una lista de archivos que coincidan con el nombre, extraiga el campo _id de los archivos que desea renombrar y pase cada valor en llamadas separadas al método rename().
Eliminar archivos
Utilice el método delete() para eliminar el documento de colección de un archivo y los fragmentos asociados de su bucket. Esto elimina el archivo. Debe especificar el archivo por su campo _id en lugar de por su nombre.
El siguiente ejemplo muestra cómo eliminar un archivo haciendo referencia a su campo _id. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
bucket.delete(ObjectId("66b3c86e672a17b6c8a4a4a9"))
await bucket.delete(ObjectId("66b3c86e672a17b6c8a4a4a9"))
Nota
El método delete() solo soporta borrar un archivo a la vez. Para borrar varios archivos, recuperar los archivos del bucket, extraiga el campo _id de los archivos que desea borrar y pase cada valor en llamadas separadas al método delete().
Documentación de la API
Para obtener más información sobre el uso de PyMongo para almacenar y recuperar archivos grandes, consulte la siguiente documentación de API: