Skip to content

Conversation

NoahStapp
Copy link
Contributor

…lename' feature - rename_by_name

@NoahStapp NoahStapp requested a review from ShaneHarvey March 24, 2025 16:27
)
if not result.matched_count:
raise NoFile(
f"no files could be renamed {new_filename} because none matched filename {filename}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: f"no files could be renamed {new_filename!r} because none matched filename {filename!r}" to make the strings more obvious.

"matched file_id %i" % (new_filename, file_id)
)

async def rename_by_name(
Copy link
Member

@ShaneHarvey ShaneHarvey Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding a new method for this, should we consider overloading the existing rename method? For example:

>>> fs.rename(file_id, "new") # rename by id
>>> fs.rename(filename="old", new_filename="new") # rename by name

The pro is we have less apis to maintain. I guess a con is that the user could accidentally mix up the file_id and filename params.

Note I'm not advocating for either, I just think we should consider it and maybe ask the spec author about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this suggestion--both methods have nearly identical bodies, so combining them makes sense. For #2218, the two methods have slightly different bodies, but still similar enough that we could do the same thing there. Thoughts?

Copy link
Member

@ShaneHarvey ShaneHarvey Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would the method signatures looks like (including type hints)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After trying this out a bit, I think it's a little too confusing/unclear to combine them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you share the signatures for posterity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

async def rename(file_id: Optional[Any], new_filename: str, filename: Optional[str] = None,...)

:param filename: The filename of the file to be renamed.
:param new_filename: The new name of the file.
:param session: a
:class:`~pymongo.client_session.AsyncClientSession`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our line length allows this to be one line now right?

        :param session: a :class:`~pymongo.client_session.AsyncClientSession`

await fs.upload_from_stream("test_file", "data I want to store!")
await fs.rename_by_name("test_file", "new_test_name")
Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with file_id -> with the given filename

elif isinstance(error, (InvalidOperation, ConfigurationError, EncryptionError)):
pass
# gridfs NoFile errors are considered client errors.
elif isinstance(error, NoFile):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest adding this to the previous elif: InvalidOperation, ConfigurationError, EncryptionError, NoFile)):

"matched file_id %i" % (new_filename, file_id)
)

def rename_by_name(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some hand written tests for this too like test_rename in test_gridfs_bucket. That way we get some signal on typing and the UX.

@NoahStapp NoahStapp requested a review from ShaneHarvey March 25, 2025 17:46
Copy link
Member

@ShaneHarvey ShaneHarvey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor comment. Otherwise LGTM.

:class:`~pymongo.encryption_options.AutoEncryptionOpts`.
- Support for $lookup in CSFLE and QE supported on MongoDB 8.1+.
- Added :meth:`gridfs.asynchronous.grid_file.AsyncGridFSBucket.rename_by_name` and :meth:`gridfs.grid_file.GridFSBucket.rename_by_name`
for more performant renaming of file revisions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of file revisions. -> of a file with multiple revisions.

@NoahStapp NoahStapp requested a review from ShaneHarvey March 26, 2025 19:01
@ShaneHarvey ShaneHarvey changed the title PYTHON-4946 - GridFS spec: Add performant 'rename all revisions by fi… PYTHON-4946 - Add GridFSBucket.rename_by_name Mar 26, 2025
ShaneHarvey
ShaneHarvey previously approved these changes Mar 28, 2025
Copy link
Member

@ShaneHarvey ShaneHarvey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, test failures are unrelated.

@NoahStapp NoahStapp merged commit a3f3ec5 into mongodb:master Mar 31, 2025
32 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants