def _ensure_file(self): if not self._file: self._file = self.__files.find_one({"_id": self.__file_id}, session=self._session) if not self._file: raise NoFile("no file in gridfs collection %r with _id %r" % (self.__files, self.__file_id))
def __init__(self, root_collection, file_id=None, file_document=None): """Read a file from GridFS Application developers should generally not need to instantiate this class directly - instead see the methods provided by :class:`~gridfs.GridFS`. Either `file_id` or `file_document` must be specified, `file_document` will be given priority if present. Raises :class:`TypeError` if `root_collection` is not an instance of :class:`~pymongo.collection.Collection`. :Parameters: - `root_collection`: root collection to read from - `file_id`: value of ``"_id"`` for the file to read - `file_document`: file document from `root_collection.files` .. versionadded:: 1.9 The `file_document` parameter. """ if not isinstance(root_collection, Collection): raise TypeError("root_collection must be an " "instance of Collection") self.__chunks = root_collection.chunks files = root_collection.files self._file = file_document or files.find_one({"_id": file_id}) if not self._file: raise NoFile("no file in gridfs collection %r with _id %r" % (files, file_id)) self.__buffer = EMPTY self.__position = 0
def delete(self, file_id: Any, session: Optional[ClientSession] = None) -> None: """Given an file_id, delete this stored file's files collection document and associated chunks from a GridFS bucket. For example:: my_db = MongoClient().test fs = GridFSBucket(my_db) # Get _id of file to delete file_id = fs.upload_from_stream("test_file", "data I want to store!") fs.delete(file_id) Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists. :Parameters: - `file_id`: The _id of the file to be deleted. - `session` (optional): a :class:`~pymongo.client_session.ClientSession` .. versionchanged:: 3.6 Added ``session`` parameter. """ _disallow_transactions(session) res = self._files.delete_one({"_id": file_id}, session=session) self._chunks.delete_many({"files_id": file_id}, session=session) if not res.deleted_count: raise NoFile("no file could be deleted because none matched %s" % file_id)
def rename( self, file_id: Any, new_filename: str, session: Optional[ClientSession] = None ) -> None: """Renames the stored file with the specified file_id. For example:: my_db = MongoClient().test fs = GridFSBucket(my_db) # Get _id of file to rename file_id = fs.upload_from_stream("test_file", "data I want to store!") fs.rename(file_id, "new_test_name") Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists. :Parameters: - `file_id`: The _id of the file to be renamed. - `new_filename`: The new name of the file. - `session` (optional): a :class:`~pymongo.client_session.ClientSession` .. versionchanged:: 3.6 Added ``session`` parameter. """ _disallow_transactions(session) result = self._files.update_one( {"_id": file_id}, {"$set": {"filename": new_filename}}, session=session ) if not result.matched_count: raise NoFile( "no files could be renamed %r because none " "matched file_id %i" % (new_filename, file_id) )
def get_last_version(self, filename): """Get a file from GridFS by ``"filename"``. Returns the most recently uploaded file in GridFS with the name `filename` as an instance of :class:`~gridfs.grid_file.GridOut`. Raises :class:`~gridfs.errors.NoFile` if no such file exists. An index on ``{filename: 1, uploadDate: -1}`` will automatically be created when this method is called the first time. :Parameters: - `filename`: ``"filename"`` of the file to get .. versionadded:: 1.6 """ self.__files.ensure_index([("filename", ASCENDING), ("uploadDate", DESCENDING)]) cursor = self.__files.find({"filename": filename}) cursor.limit(-1).sort("uploadDate", DESCENDING) try: grid_file = cursor.next() return GridOut(self.__collection, grid_file["_id"]) except StopIteration: raise NoFile("no file in gridfs with filename %r" % filename)
def __init__(self, root_collection, file_id): """Read a file from GridFS Application developers should generally not need to instantiate this class directly - instead see the methods provided by :class:`~gridfs.GridFS`. Raises :class:`TypeError` if `root_collection` is not an instance of :class:`~pymongo.collection.Collection`. :Parameters: - `root_collection`: root collection to read from - `file_id`: value of ``"_id"`` for the file to read """ if not isinstance(root_collection, Collection): raise TypeError("root_collection must be an " "instance of Collection") self.__chunks = root_collection.chunks self._file = root_collection.files.find_one({"_id": file_id}) if not self._file: raise NoFile("no file in gridfs collection %r with _id %r" % (root_collection, file_id)) self.__buffer = "" self.__position = 0
def get_version( self, filename: Optional[str] = None, version: Optional[int] = -1, session: Optional[ClientSession] = None, **kwargs: Any ) -> GridOut: """Get a file from GridFS by ``"filename"`` or metadata fields. Returns a version of the file in GridFS whose filename matches `filename` and whose metadata fields match the supplied keyword arguments, as an instance of :class:`~gridfs.grid_file.GridOut`. Version numbering is a convenience atop the GridFS API provided by MongoDB. If more than one file matches the query (either by `filename` alone, by metadata fields, or by a combination of both), then version ``-1`` will be the most recently uploaded matching file, ``-2`` the second most recently uploaded, etc. Version ``0`` will be the first version uploaded, ``1`` the second version, etc. So if three versions have been uploaded, then version ``0`` is the same as version ``-3``, version ``1`` is the same as version ``-2``, and version ``2`` is the same as version ``-1``. Raises :class:`~gridfs.errors.NoFile` if no such version of that file exists. :Parameters: - `filename`: ``"filename"`` of the file to get, or `None` - `version` (optional): version of the file to get (defaults to -1, the most recent version uploaded) - `session` (optional): a :class:`~pymongo.client_session.ClientSession` - `**kwargs` (optional): find files by custom metadata. .. versionchanged:: 3.6 Added ``session`` parameter. .. versionchanged:: 3.1 ``get_version`` no longer ensures indexes. """ query = kwargs if filename is not None: query["filename"] = filename _disallow_transactions(session) cursor = self.__files.find(query, session=session) if version is None: version = -1 if version < 0: skip = abs(version) - 1 cursor.limit(-1).skip(skip).sort("uploadDate", DESCENDING) else: cursor.limit(-1).skip(version).sort("uploadDate", ASCENDING) try: doc = next(cursor) return GridOut(self.__collection, file_document=doc, session=session) except StopIteration: raise NoFile("no version %d for filename %r" % (version, filename))
def open_download_stream_by_name(self, filename, revision=-1, session=None): """Opens a Stream from which the application can read the contents of `filename` and optional `revision`. For example:: my_db = MongoClient().test fs = GridFSBucket(my_db) grid_out = fs.open_download_stream_by_name("test_file") contents = grid_out.read() Returns an instance of :class:`~gridfs.grid_file.GridOut`. Raises :exc:`~gridfs.errors.NoFile` if no such version of that file exists. Raises :exc:`~ValueError` filename is not a string. :Parameters: - `filename`: The name of the file to read from. - `revision` (optional): Which revision (documents with the same filename and different uploadDate) of the file to retrieve. Defaults to -1 (the most recent revision). - `session` (optional): a :class:`~pymongo.client_session.ClientSession` :Note: Revision numbers are defined as follows: - 0 = the original stored file - 1 = the first revision - 2 = the second revision - etc... - -2 = the second most recent revision - -1 = the most recent revision .. versionchanged:: 3.6 Added ``session`` parameter. """ validate_string("filename", filename) query = {"filename": filename} cursor = self._files.find(query, session=session) if revision < 0: skip = abs(revision) - 1 cursor.limit(-1).skip(skip).sort("uploadDate", DESCENDING) else: cursor.limit(-1).skip(revision).sort("uploadDate", ASCENDING) try: grid_file = next(cursor) return GridOut(self._collection, file_document=grid_file, session=session) except StopIteration: raise NoFile("no version %d for filename %r" % (revision, filename))
def _ensure_file(self) -> None: if not self._file: _disallow_transactions(self._session) self._file = self.__files.find_one({"_id": self.__file_id}, session=self._session) if not self._file: raise NoFile("no file in gridfs collection %r with _id %r" % (self.__files, self.__file_id))
def get_version(self, filename=None, version=-1, **kwargs): """Get a file from GridFS by ``"filename"`` or metadata fields. Returns a version of the file in GridFS whose filename matches `filename` and whose metadata fields match the supplied keyword arguments, as an instance of :class:`~gridfs.grid_file.GridOut`. Version numbering is a convenience atop the GridFS API provided by MongoDB. If more than one file matches the query (either by `filename` alone, by metadata fields, or by a combination of both), then version ``-1`` will be the most recently uploaded matching file, ``-2`` the second most recently uploaded, etc. Version ``0`` will be the first version uploaded, ``1`` the second version, etc. So if three versions have been uploaded, then version ``0`` is the same as version ``-3``, version ``1`` is the same as version ``-2``, and version ``2`` is the same as version ``-1``. Raises :class:`~gridfs.errors.NoFile` if no such version of that file exists. An index on ``{filename: 1, uploadDate: -1}`` will automatically be created when this method is called the first time. :Parameters: - `filename`: ``"filename"`` of the file to get, or `None` - `version` (optional): version of the file to get (defualts to -1, the most recent version uploaded) - `**kwargs` (optional): find files by custom metadata. .. versionchanged:: 1.11 `filename` defaults to None; .. versionadded:: 1.11 Accept keyword arguments to find files by custom metadata. .. versionadded:: 1.9 """ database = self.__database if not database.slave_okay and not database.read_preference: self.__files.ensure_index([("filename", ASCENDING), ("uploadDate", DESCENDING)]) query = kwargs if filename is not None: query["filename"] = filename cursor = self.__files.find(query) if version < 0: skip = abs(version) - 1 cursor.limit(-1).skip(skip).sort("uploadDate", DESCENDING) else: cursor.limit(-1).skip(version).sort("uploadDate", ASCENDING) try: grid_file = cursor.next() return GridOut(self.__collection, file_document=grid_file) except StopIteration: raise NoFile("no version %d for filename %r" % (version, filename))
async def get_version(self, filename=None, version=-1, **kwargs) -> GridOut: """Get a file from GridFS by ``"filename"`` or metadata fields. Returns a version of the file in GridFS whose filename matches `filename` and whose metadata fields match the supplied keyword arguments, as an instance of :class:`~gridfs.grid_file.GridOut`. Version numbering is a convenience atop the GridFS API provided by MongoDB. If more than one file matches the query (either by `filename` alone, by metadata fields, or by a combination of both), then version ``-1`` will be the most recently uploaded matching file, ``-2`` the second most recently uploaded, etc. Version ``0`` will be the first version uploaded, ``1`` the second version, etc. So if three versions have been uploaded, then version ``0`` is the same as version ``-3``, version ``1`` is the same as version ``-2``, and version ``2`` is the same as version ``-1``. Raises :class:`~gridfs.errors.NoFile` if no such version of that file exists. :Parameters: - `filename`: ``"filename"`` of the file to get, or `None` - `version` (optional): version of the file to get (defaults to -1, the most recent version uploaded) - `**kwargs` (optional): find files by custom metadata. """ query = kwargs if filename is not None: query['filename'] = filename cursor = self.__files.find(query) if version < 0: skip = abs(version) - 1 cursor.limit(-1).skip(skip).sort('uploadDate', DESCENDING) else: cursor.limit(-1).skip(version).sort('uploadDate', ASCENDING) async for grid_file in cursor: return GridOut(self.__collection, file_document=grid_file) raise NoFile('no version %d for filename %r' % (version, filename))
def get_version(self, filename, version=-1): """Get a file from GridFS by ``"filename"``. Returns a version of the file in GridFS with the name `filename` as an instance of :class:`~gridfs.grid_file.GridOut`. Version ``-1`` will be the most recently uploaded, ``-2`` the second most recently uploaded, etc. Version ``0`` will be the first version uploaded, ``1`` the second version, etc. So if three versions have been uploaded, then version ``0`` is the same as version ``-3``, version ``1`` is the same as version ``-2``, and version ``2`` is the same as version ``-1``. Raises :class:`~gridfs.errors.NoFile` if no such version of that file exists. An index on ``{filename: 1, uploadDate: -1}`` will automatically be created when this method is called the first time. :Parameters: - `filename`: ``"filename"`` of the file to get - `version` (optional): version of the file to get (defualts to -1, the most recent version uploaded) .. versionadded:: 1.9 """ self.__files.ensure_index([("filename", ASCENDING), ("uploadDate", DESCENDING)]) cursor = self.__files.find({"filename": filename}) if version < 0: skip = abs(version) - 1 cursor.limit(-1).skip(skip).sort("uploadDate", DESCENDING) else: cursor.limit(-1).skip(version).sort("uploadDate", ASCENDING) try: grid_file = cursor.next() return GridOut(self.__collection, grid_file["_id"]) except StopIteration: raise NoFile("no version %d for filename %r" % (version, filename))
def delete(self, file_id): """Given an file_id, delete this stored file's files collection document and associated chunks from a GridFS bucket. For example:: my_db = MongoClient().test fs = GridFSBucket(my_db) # Get _id of file to delete file_id = fs.upload_from_stream("test_file", "data I want to store!") fs.delete(file_id) Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists. :Parameters: -`file_id`: The _id of the file to be deleted. """ res = self._files.delete_one({"_id": file_id}) self._chunks.delete_many({"files_id": file_id}) if not res.deleted_count: raise NoFile("no file could be deleted because none matched %s" % file_id)
def rename(self, file_id, new_filename): """Renames the stored file with the specified file_id. For example:: my_db = MongoClient().test fs = GridFSBucket(my_db) # Get _id of file to rename file_id = fs.upload_from_stream("test_file", "data I want to store!") fs.rename(file_id, "new_test_name") Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists. :Parameters: - `file_id`: The _id of the file to be renamed. - `new_filename`: The new name of the file. """ result = self._files.update_one({"_id": file_id}, {"$set": {"filename": new_filename}}) if not result.matched_count: raise NoFile("no files could be renamed %r because none " "matched file_id %i" % (new_filename, file_id))
async def _ensure_file(self): if not self._file: self._file = await self.__files.find_one({'_id': self.__file_id}) if not self._file: raise NoFile('no file in gridfs collection %r with _id %r' % (self.__files, self.__file_id))