Кастомная система хранения для GridFS (MongoDB)? - PullRequest
4 голосов
/ 19 сентября 2009

Может ли кто-нибудь указать мне какие-либо проекты / приложения django, которые предоставляют настраиваемую систему хранения с возможностью подключения, чтобы я мог использовать GridFS с Django для хранения файловых загрузок?

Я нашел django-mongodb, но, похоже, он не поддерживает GridFS и django-хранилища.

Я планирую запустить mysql для обычных требований к базе данных и использовать только mongodb для хранения файлов, поэтому, чтобы было ясно, я не хочу использовать mongodb в качестве основной базы данных.

Ответы [ 4 ]

3 голосов
/ 19 сентября 2009

Я работаю над PyMongo, драйвером Python MongoDB, и не слышал ни о каком проекте по предоставлению пользовательского хранилища для Django с использованием GridFS. Похоже, что написать на вершине PyMongo будет не сложно: возможно, это прямой перевод GridFS API на Django API хранения . Возможно, в какой-то момент можно было бы взглянуть на то, как можно собрать что-то вместе, но это был бы отличный проект с открытым исходным кодом для всех, кто хочет принять участие.

1 голос
/ 05 марта 2011

Мне нужно было именно это для EDMS Майя , подключаемого хранилища и разделения базы данных. Используя последнюю библиотеку Майкла Дирольфа 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
1 голос
/ 02 ноября 2010

Я недавно реализовал поддержку GridFS в Mongoengine , которую вы могли бы попробовать. Это включает в себя серверную часть хранилища Django, которую вы можете подключить прямо к своим проектам и использовать с ImageField и т. Д. Я использую эти технологии в производстве, и до сих пор это прекрасно работает.

1 голос
/ 05 сентября 2010

django-mongodb-engine может стоить посмотреть, так как это позволяет вам делать это без необходимости вносить изменения в существующий код Django.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...