Armazenar arquivos grandes
Nesta página
Visão geral
Neste guia, você pode aprender como armazenar e recuperar arquivos grandes no MongoDB usando GridFS. O GridFS é uma especificação implementada pelo PyMongo que descreve como dividir os arquivos em blocos ao armazená-los e remontá-los ao recuperá-los. A implementação do driver do GridFS é uma abstração que gerencia as operações e a organização do armazenamento de arquivos.
Você deve usar GridFS se o tamanho dos arquivos exceder o limite de tamanho do documento BSON de 16MB. Para obter informações mais detalhadas sobre se o GridFS é adequado para seu caso de uso, consulte GridFS no manual do MongoDB Server .
As seções a seguir descrevem as operações do GridFS e como executá-las.
Como funciona o GridFS
O GridFS organiza os arquivos em um bucket, um grupo de coleções do MongoDB que contém os blocos de arquivos e as informações que os descrevem. O bloco contém as seguintes coleções, nomeadas usando a convenção definida na especificação do GridFS:
A coleção
chunks
armazena os blocos de arquivo binário.A coleção
files
armazena os metadados do arquivo.
Quando você cria um novo bloco GridFS, o driver cria as coleções anteriores, prefixadas com o nome de bloco padrão fs
, a menos que você especifique um nome diferente. O driver também cria um índice em cada coleção para garantir a recuperação eficiente de arquivos e metadados relacionados. O driver cria o bucket GridFS, se ele não existir, somente quando a primeira operação de gravação for executada. O driver cria índices somente se eles não existirem e quando o bucket estiver vazio. Para obter mais informações sobre os índices do GridFS, consulte Índices do GridFS no manual do MongoDB Server .
Ao armazenar arquivos com GridFS, o driver divide os arquivos em partes menores, cada uma representada por um documento separado na coleção do chunks
. Ele também cria um documento na coleção files
que contém um ID de arquivo, nome de arquivo e outros metadados de arquivo. Você pode carregar o arquivo da memória ou de um stream. Confira o diagrama a seguir para ver como o GridFS divide os arquivos quando carregados em um bucket.
Ao recuperar arquivos, o GridFS obtém os metadados da coleção files
no contêiner especificado e utiliza as informações para reconstruir o arquivo a partir de documentos na coleção chunks
. Você pode ler o arquivo na memória ou enviá-lo para um fluxo.
Crie um intervalo GridFS
Para armazenar ou recuperar arquivos do GridFS, crie um bucket do GridFS chamando o construtor GridFSBucket()
e passando uma instância Database
. Pode utilizar a instância GridFSBucket
para chamar operações de leitura e escrita nos ficheiros no seu bloco.
client = MongoClient("<connection string>") db = client["db"] bucket = gridfs.GridFSBucket(db)
Para criar ou referenciar um contêiner com um nome personalizado diferente do nome padrão fs
, passe seu nome de contêiner como o segundo parâmetro para o construtor GridFSBucket()
, como mostrado abaixo:
custom_bucket = gridfs.GridFSBucket(db, bucket_name="myCustomBucket")
Fazer upload de arquivos
Use o método open_upload_stream()
da classe GridFSBucket
para criar um fluxo de upload para um determinado nome de arquivo. O método open_upload_stream()
permite que você especifique informações de configuração, como o tamanho do bloco do arquivo e outros pares de campo/valor a serem armazenados como metadados. Defina estas opções como parâmetros de open_upload_stream()
, como mostrado no seguinte exemplo de código:
with bucket.open_upload_stream( "my_file", chunk_size_bytes=1048576, metadata={"contentType": "text/plain"} ) as grid_in: grid_in.write("data to store")
Recuperar informações do arquivo
Nesta seção, você pode aprender como recuperar metadados de arquivo armazenados na coleção files
do contêiner GridFS. Os metadados contêm informações sobre o arquivo a que se refere, incluindo:
O
_id
do arquivoO nome do arquivo
O tamanho/comprimento do arquivo
A data e a hora do carregamento
Um documento
metadata
no qual você pode armazenar qualquer outra informação
Para recuperar arquivos de um GridFS , chame o método find()
na instância do GridFSBucket
. O método retorna uma instância do Cursor
da qual você pode acessar os resultados. Para saber mais sobre Cursor
objetos no PyMongo, consulte Acessar dados de um cursor.
O seguinte exemplo de código mostra como recuperar e imprimir metadados de arquivo de todos os seus arquivos em um bucket GridFS. Ele usa a sintaxe for...in
para percorrer o iterável Cursor
e exibir os resultados:
for file_doc in bucket.find({}): print(file_doc)
O método find()
aceita várias especificações de query. Você pode usar seus parâmetros para especificar a ordem de classificação, o número máximo de documentos a serem devolvidos e o número de documentos a serem ignorados antes de retornar. Para saber mais sobre como consultar o MongoDB, consulte Retrieve Data (Recuperar dados).
Baixar arquivos
Você pode baixar arquivos do seu banco de dados MongoDB utilizando o método open_download_stream_by_name()
do GridFSBucket
para criar um stream de download.
O exemplo a seguir mostra como baixar um arquivo referenciado pelo nome de arquivo, "my_file"
e ler seu conteúdo:
file = bucket.open_download_stream_by_name("my_file") contents = file.read()
Observação
Se houver vários documentos com o mesmo valor de filename
, o GridFS transmitirá o arquivo mais recente com o nome fornecido (conforme determinado pelo campo uploadDate
).
Alternativamente, você pode utilizar o método open_download_stream()
, que utiliza o campo _id
de um arquivo como um parâmetro:
file = bucket.open_download_stream(ObjectId("66b3c86e672a17b6c8a4a4a9")) contents = file.read()
Observação
A API de streaming do GridFS não pode carregar blocos parciais. Quando um fluxo de download precisa extrair um bloco do MongoDB, ele puxa todo o bloco para a memória. O tamanho padrão do bloco de 255-kilobyte geralmente é suficiente, mas você pode reduzir o tamanho do bloco para reduzir a sobrecarga de memória.
Renomear arquivos
Utilize o método rename()
para atualizar o nome de um arquivo GridFS em seu bucket. Você deve especificar o arquivo para renomear pelo campo _id
em vez do nome do arquivo.
O exemplo a seguir mostra como atualizar o filename
campo "new_file_name"
para fazendo referência ao _id
campo de um documento:
bucket.rename(ObjectId("66b3c86e672a17b6c8a4a4a9"), "new_file_name")
Observação
O método rename()
aceita a atualização do nome de somente um arquivo por vez. Para renomear vários arquivos, recupere uma lista de arquivos correspondentes ao nome do arquivo do contêiner, extraia o campo _id
dos arquivos que você deseja renomear e passe cada valor em chamadas separadas para o método rename()
.
Excluir arquivos
Use o método delete()
para remover o documento de collection de um arquivo e os chunks associados do seu bucket. Isso exclui efetivamente o arquivo. Você deve especificar o arquivo pelo campo _id
em vez do nome do arquivo.
O seguinte exemplo mostra como excluir um arquivo referenciando seu campo _id
:
bucket.delete(ObjectId("66b3c86e672a17b6c8a4a4a9"))
Observação
O método delete()
suporta a exclusão de somente um arquivo de cada vez. Para excluir vários arquivos, recupere os arquivos do bucket, extraia o campo _id
dos arquivos que deseja excluir e passe cada valor em chamadas separadas para o método delete()
.
Documentação da API
Para saber mais sobre como usar o PyMongo para armazenar e recuperar arquivos grandes, consulte a seguinte documentação da API: