diff --git a/fiftyone/core/dataset.py b/fiftyone/core/dataset.py index 59070f907e..916ff0125a 100644 --- a/fiftyone/core/dataset.py +++ b/fiftyone/core/dataset.py @@ -7777,7 +7777,7 @@ def _clone_dataset_or_view(dataset_or_view, name, persistent): # Clone dataset document # - dataset_doc = dataset._doc.copy_with_new_id() + dataset_doc = dataset._doc.copy(new_id=True) _id = dataset_doc.id sample_collection_name = _make_sample_collection_name(_id) @@ -8249,12 +8249,12 @@ def _clone_extras(src_dataset, dst_dataset): def _clone_reference_doc(ref_doc): - _ref_doc = ref_doc.copy_with_new_id() + _ref_doc = ref_doc.copy(new_id=True) return _ref_doc def _clone_run(run_doc): - _run_doc = run_doc.copy_with_new_id() + _run_doc = run_doc.copy(new_id=True) _run_doc.results = None # Unfortunately the only way to copy GridFS files is to read-write them... diff --git a/fiftyone/core/odm/document.py b/fiftyone/core/odm/document.py index c550aae3d4..b263e5bacb 100644 --- a/fiftyone/core/odm/document.py +++ b/fiftyone/core/odm/document.py @@ -584,18 +584,25 @@ class Document(BaseDocument, mongoengine.Document): def _doc_name(cls): return "Document" - def copy_with_new_id(self): - """Returns a copy of this document with a new ID""" - doc_copy = self.copy() - new_id = bson.ObjectId() + def copy(self, new_id=False): + """Returns a deep copy of the document. - # pylint: disable=no-member - id_field = self._meta.get("id_field", "id") - doc_copy.set_field(id_field, new_id) + Args: + new_id (False): Whether to generate a new ID for the copied + document locally. By default, ID is set to None which causes + ID generation to be done on the server. + """ + doc_copy = super().copy() + if new_id: + new_id = bson.ObjectId() + + # pylint: disable=no-member + id_field = self._meta.get("id_field", "id") + doc_copy.set_field(id_field, new_id) - # Setting _created explicitly as True because we know this is a new - # document - doc_copy._created = True + # Setting _created explicitly as True because we know this is a new + # document + doc_copy._created = True return doc_copy def reload(self, *fields, **kwargs): diff --git a/tests/unittests/odm_tests.py b/tests/unittests/odm_tests.py index b2a9eaabc6..85e01ab4bc 100644 --- a/tests/unittests/odm_tests.py +++ b/tests/unittests/odm_tests.py @@ -40,17 +40,20 @@ def test_doc_copy_with_new_id(self): sample_collection_name="samples.unique", version="51.51", ) - dataset_doc.save() - # Copy with new ID -- ID should be new, _created should be True - doc_copy = dataset_doc.copy_with_new_id() - self.assertNotEqual( - dataset_doc.get_field("id"), doc_copy.get_field("id") - ) - self.assertTrue(doc_copy._created) + try: + dataset_doc.save() + + # Copy with new ID -- ID should be new, _created should be True + doc_copy = dataset_doc.copy(new_id=True) + self.assertNotEqual( + dataset_doc.get_field("id"), doc_copy.get_field("id") + ) + self.assertTrue(doc_copy._created) - # Now if we set ID to be same, the doc should be the same - doc_copy.set_field("id", dataset_doc.get_field("id")) - self.assertEqual(doc_copy, dataset_doc) + # Now if we set ID to be same, the doc should be the same + doc_copy.set_field("id", dataset_doc.get_field("id")) + self.assertEqual(doc_copy, dataset_doc) - dataset_doc.delete() + finally: + dataset_doc.delete()