Python使用MongoDB-GridFS进行文档管理

Mongodb 专栏收录该内容
13 篇文章 0 订阅

问题引入:

mongodb如何存取图片及等其他非文档型文件,或者说大于16M的文件。例如pdf文件,大图片文件等。

解决方案

MongoDB内置一套文件系统名为GridFS(Grid File System),我们可以使用它来存储大于16M的文件。

GridFS具有分布式管理文件的能力,可以突破一般文件系统对file的限制,分段存储,不像普通文件系统是整个存储的。这样读取大型文件时就不会占用大量的内存。

GridFS会将文件存储在两个Document里:

1.Chunks用来存储二进制数据
2.Files用于存储基本文件信息

在这里插入图片描述

gridfs介绍

GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等),适合于不常改变但是经常需要连续访问的大文件。GridFS 也是文件存储的一种方式,但是它是存储在MonoDB的集合中。

GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/个,每个chunk将作为MongoDB的一个文档(document)被存储在chunks集合中。

其中,files中存储文件的元信息,默认使用集合为fs.files,键定义如下:

_id 主键
length 文件所包含的字节数
chunkSize 组成文件的每个块的大小,单位为字节,默认值为256KB,可调整
uploadDate 文件被上传到GridFS的日期
md5 文件内容的MD5校验值,该值由服务器端测试得到

在这里插入图片描述

每一个文件存储的各个chunk的files_id相同
在这里插入图片描述

代码演练

import pymongo
from gridfs import GridFS
from bson.objectid import ObjectId


class MongoGridFS(object):
    UploadCache = "uploadcache"
    dbURL = "mongodb://192.168.20.120:27010"

    def __init__(self, params):
        '''
        Constructor
        '''
        # 上传文件

    def upLoadFile(self, file_coll, file_name, data_link):
        """
        上传文件
        :param file_coll: 集合名
        :param file_name: 文件名(自定义属性字段)
        :param data_link: 文件链接(自定义属性字段)
        :return: 返回files_id
        """
        client = pymongo.MongoClient(self.dbURL)

        db = client["xddq_device_maintenance"]

        filter_condition = {"filename": file_name, "url": data_link, 'version':2}
        gridfs_col = GridFS(db, collection=file_coll)
        file_ = "0"
        query = {"filename": ""}
        query["filename"] = file_name

        if gridfs_col.exists(query):
            print('已经存在该文件')
        else:

            with open(file_name, 'rb') as file_r:
                file_data = file_r.read()
                file_ = gridfs_col.put(data=file_data, **filter_condition)  # 上传到gridfs

                print(file_)

        return file_
        # 按文件名获取文档

    def downLoadFile(self, file_coll, file_name, out_name, ver=-1):
        """
        按文件名下载
        :param file_coll:集合名
        :param file_name:文件名
        :param out_name: 下载下来的文件名
        :param ver: 版本号,默认-1表示最近一次的记录
        :return:
        """
        client = pymongo.MongoClient(self.dbURL)

        db = client["xddq_device_maintenance"]

        gridfs_col = GridFS(db, collection=file_coll)

        file_data = gridfs_col.get_version(filename=file_name, version=ver).read()

        with open(out_name, 'wb') as file_w:
            file_w.write(file_data)

    # 按文件_Id获取文档
    def downLoadFilebyID(self, file_coll, _id, out_name):
        """
        按文件id获取文件
        :param file_coll: 集合名
        :param _id: 文件id ===> fiels_id
        :param out_name: 下载后的文件名称
        :return: 
        """
        client = pymongo.MongoClient(self.dbURL)

        db = client["xddq_device_maintenance"]

        gridfs_col = GridFS(db, collection=file_coll)

        O_Id = ObjectId(_id)

        gf = gridfs_col.get(file_id=O_Id)
        file_data = gf.read()
        with open(out_name, 'wb') as file_w:
            file_w.write(file_data)

        return gf.filename


if __name__ == '__main__':
    a = MongoGridFS("")
    file = a.upLoadFile("test","a.pdf","")  # 上傳名为a.pdf的文件
    a.downLoadFile("test","a.pdf","c.pdf")  # 按文件名下载文件保存到c.pdf
    ll = a.downLoadFilebyID("test", 'file', "b.pdf")  # 按files_id下载文件保存到b.pdf
结果:

在这里插入图片描述

  • 1
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值