》现如今进入到web3.0时代,数据的形式不局限于文字,还有语音、视频、图片等
》普通SQL数据库不适合存储文件,但是MongoDB却额外提供了文件存储方式,即:GridFS
》GridFS
是MongoDB的文件存储方案,主要用于存储超过16M(BSON文件限制)的文件(如:图片、音频等),对大文件有着更好的性能
》GridFS
使用两个集合来存储文件,一个是chunks
集合,用来存放文件;另一个集合是files
,用于存储文件的元数据
》GridFS
会把文件分割成若干chunks(256KB)
,然后在files记录他们
》默认情况下MongoClient
不提供GridFS
,需要创建GridFS
对象
from gridfs import GridFS
db = client.school
gfs = GridFS(db, collection="book")
// 创建GridFS对象,传入参数一:数据库,参数二:集合
》put函数
可以把文件存储到GridFS
中
file = open("D:/qq.txt", "rb") // 文件位置
args = {"type": "txt", "keyword": "qq"} // 描述文件,以字典的形式进行存储,字典中的属性可以自定义
gfs.put(file, filename="qq.txt", **args)
// 调用put()函数,传入参数一:文件位置,参数二:filename,参数三:描述文件的元数据
file.close() // 关闭文件
执行完以上操作,会发现在数据表中多了两个集合,即chunks
和files
chunks
中保存上传文件,以数据包的形式进行存储,每个数据大小为256KB;
files
中存放文件信息,包括(id、自定义描述文件信息、文件大小(以字节为单位)、上传日期(格林尼治时间))
》find
和find_one
函数可以查询GridFS
中存储的文件
import math
book = gfs.find_one({"filename":"qq.txt"})
print(book.filename)
print("%dM" % (math.ceil(book.length / 1024 / 1024)))
# 根据文件名查打印文件体积 math.ceil()函数将小数转换为整数,所以需要额外导入math包
import datetime # 日期转换
books = gfs.find({"type":"txt"})
for book in books:
# UTC转换成北京时间
uploadDate = book.uploadDate + datetime.timedelta(hours=8)
# 格式化日期
uploadDate = uploadDate.strftime("%Y-%M-%D %H:%M:%S")
print(book._id, book.filename, uploadDate)
》exists
函数可以判断GridFS
是否存储某个文件
from bson.objectid import ObjectId
rs = gfs.exists(ObjectId("5c1dca81db1df328ec1cb67c"))
# exists()中的id不能直接写字符串,需要封装成ObjectId对象,所以需要导入ObjectId包
print(rs)
rs = gfs.exists(**{"type":"txt"}) # 注意,需要在字典参数前加上**
print(rs) # 返回True或False
》get
函数可以从GridFS
中读取文件,并且只能通过主键查找文件,且一次只返回一个文件内容
from bson.objectid import ObjectId
document = gfs.get(ObjectId("5c1dca81db1df328ec1cb67c")) # 还是需要导入ObjectId包
file = open("D:/1111.txt", "wb")
file.write(document.read()) # 获取文件并写入到硬盘中
file.close()
》delete
函数可以从GridFS
中删除文件,并且只能通过主键先查找记录
from bson.objectid import ObjectId
....
gfs.delete(ObjectId("5c1dca81db1df328ec1cb67c"))