🙄 서버 용량이 넉넉하지 않은데 괜찮을지.... 단순 document 만 저장해서 사용할 때는 document 당 용량이 작으니까 저장 정책에 대해 신경쓰지 않았는데 gridfs 를 이용해서 대용량의 파일을 db 서버에서 관리할 시 저장정책에 대해 신경쓰지 않을 수 없음
아래 내용은 gridFS 뿐 아니라, mongodb 자체에 대한 것
RDBS 는 delete 시 물리적인 디스크 공간이 확보되지만, mongodb 는 remove 로 document 를 삭제하거나 collection 을 drop 해도 실제 디스크의 물리적인 공간이 확보되지 않는다. mongodb 는 디스크를 미리 할당해서 사용하는 방식인 storage engine 방식을 사용하기 때문. 따라서 실제 확보를 위해서는...
①db.repairDatabase()를 통해 백업 세트를 복제하여 재구성: 현재 내용을 복제를 한 뒤 재구성을 하는 거라서 현재 디스크 사용량의 2배가 필요하고 실행시간이 길며, 재구성 중 lock 이 걸림
② collection 마다 compact 명령을 수행: 2gb 정도 필요하며, 이미 할당되었던 공간의 파편화를 정리하여 사용가능하게 해주는 방식으로, 실제 가용 용량이 늘어나지는 않는다고 함
③ TTL Index: 약간 결이 다른 내용인데, 일정 시간이 지나면 document 를 자동으로 삭제하도록(백그라운드 작업) 애초에 collection 을 구성하는 것. 단 이는 gridfs 에는 적합하지 않아보임(컬렉션이 files, chunks 로 분리되어 있고, files 에서만 TTL Index 를 만들어서 삭제한다고 해봐야 실제 데이터에 해당하는 chunks 에는 남아있으므로 의미가 없음)
from pymongo import MongoClient
from gridfs import GridFS
# database 연결 및 생성
client = MongoClient(host='localhost', port=27017)
mydb = client['cointreau']
client.list_database_names()
['admin', 'local', 'cointreau']
# gridFS 객체 생성
client.fs = GridFS(mydb)
# file 을 binary 형태로 읽어서 db에 저장
with open('./abcd.jpg', 'rb') as data:
# filename 이 별로 의미가 없는듯, 임의의 parameter user/jobid 을 추가로 넣어서 이걸 바탕으로 확인 가능
uid = client.fs.put(data, filename='abcd.jpg', user='cointreau', jobid='1234')
uid
ObjectId('634cec9bba27109b61ef6b8e')
# file name으로 file get
print('## 파일 리스트')
file_lst = list(client.fs.find())
for ID in file_lst:
print(ID._id, ID.filename)
# 특정 field 로 get
print('\n## 특정 field로 get')
for ID in client.fs.find({'user': 'yun'}):
print(ID._id, ID.filename, ID.user, ID.jobid)
## 파일 리스트
634cec9bba27109b61ef6b8e abcd.jpg
## 특정 field로 get
634cec9bba27109b61ef6b8e abcd.jpg cointreau 1234
# delete 는 파일 id 로 할 수 있음, 여기서만 지우면 files/chunks 컬렉션에서 모두 지워짐.
client.fs.delete(file_lst[0]._id)
참조 사이트
https://comphy.tistory.com/m/879
https://severalnines.com/blog/storing-files-mongodb-gridfs/
https://studio3t.com/knowledge-base/articles/mongodb-gridfs/
https://parkingcloud.github.io/skills/skills_mongodb/