GRIDFS (MongoDB) 용 사용자 정의 저장 시스템?
문제
누구든지 플러그 가능한 커스텀 스토리지 시스템을 제공하는 프로젝트/django 앱을 지적하여 Django와 함께 GRIDFS를 사용하여 파일 업로드를 저장할 수 있습니까?
나는 django-mongodB를 발견했지만 GRIDFS를 지원하는 것 같지 않으며 Django-Storages도하지 않는 것 같습니다.
나는 일반 데이터베이스 시험을 위해 MySQL을 실행하고 파일 스토리지에 MongoDB 만 사용하여 MongoDB를 내 주요 데이터베이스로 사용하고 싶지 않다는 것을 알 수 있습니다.
해결책
나는 Mongodb Python 드라이버 인 Pymongo에서 일하고 있으며 GRIDFS를 사용하여 Django에 맞춤형 스토리지를 제공하는 프로젝트에 대해 들어 보지 못했습니다. 이것은 Pymongo 위에 글을 쓰는 것이 그리 어렵지 않은 것처럼 보입니다. 아마도 아마도 GRIDFS API 에 Django Storage API. 어쩌면 어느 시점에서 무언가를 던지는 것을 살펴볼 수도 있지만, 이것은 참여하고자하는 사람에게는 훌륭한 오픈 소스 프로젝트 일 것입니다.
다른 팁
나는 최근에 그것을 구현했다 MongoEngine에서 GRIDFS 지원 체크 아웃하고 싶을 수도 있습니다. 여기에는 Django Storage 백엔드가 포함되어 있으며 프로젝트에 바로 연결하고 Imagefield 등을 사용할 수 있습니다. 저는 이러한 기술을 생산에 사용하고 있으며 지금까지 크게 유지되고 있습니다.
Django-MongoDB-Engine 기존 Django 코드를 변경할 필요없이 그렇게 할 수 있으므로 볼만한 가치가 있습니다.
나는 그것을 정확히 필요로했다 마야 EDM, 플러그 가능한 스토리지 및 데이터베이스 분리. Michael Dirolf의 최신 Pymongo 라이브러리를 사용하여 기본 수업을받는 것은 다소 사소했습니다.
그것을 사용하려면 :
from gridfsstorage import GridFSStorage
file = models.FileField(storage=GridFSStorage())
gridfsstorage.py 파일 :
import os
from django.core.files.storage import Storage
from django.utils.encoding import force_unicode
from django.conf import settings
from pymongo import Connection
from gridfs import GridFS
class GridFSStorage(Storage):
def __init__(self, *args, **kwargs):
self.db = Connection(host=settings.GRIDFS_HOST,
port=settings.GRIDFS_PORT)[settings.DATABASE_NAME]
self.fs = GridFS(self.db)
def save(self, name, content):
while True:
try:
# This file has a file path that we can move.
if hasattr(content, 'temporary_file_path'):
self.move(content.temporary_file_path(), name)
content.close()
# This is a normal uploadedfile that we can stream.
else:
# This fun binary flag incantation makes os.open throw an
# OSError if the file already exists before we open it.
newfile = self.fs.new_file(filename=name)
try:
for chunk in content.chunks():
newfile.write(chunk)
finally:
newfile.close()
except Exception, e:
raise
else:
# OK, the file save worked. Break out of the loop.
break
return name
def open(self, name, *args, **kwars):
return self.fs.get_last_version(name)
def delete(self, name):
oid = self.fs.get_last_version(name)._id
self.fs.delete(oid)
def exists(self, name):
return self.fs.exists(filename=name)
def path(self, name):
return force_unicode(name)
def size(self, name):
return self.fs.get_last_version(name).length
def move(self, old_file_name, name, chunk_size=1024*64):
# first open the old file, so that it won't go away
old_file = open(old_file_name, 'rb')
try:
newfile = self.fs.new_file(filename=name)
try:
current_chunk = None
while current_chunk != '':
current_chunk = old_file.read(chunk_size)
newfile.write(current_chunk)
finally:
newfile.close()
finally:
old_file.close()
try:
os.remove(old_file_name)
except OSError, e:
# Certain operating systems (Cygwin and Windows)
# fail when deleting opened files, ignore it. (For the
# systems where this happens, temporary files will be auto-deleted
# on close anyway.)
if getattr(e, 'winerror', 0) != 32 and getattr(e, 'errno', 0) != 13:
raise