Skip to content

Commit

Permalink
Merge pull request #4729 from voxel51/fix/mongoengine-document-misc-bugs
Browse files Browse the repository at this point in the history
fix copied doc updates not insert
  • Loading branch information
brimoor authored Sep 12, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents 25bfc40 + 86aad06 commit 8811fd9
Showing 3 changed files with 55 additions and 12 deletions.
20 changes: 8 additions & 12 deletions fiftyone/core/dataset.py
Original file line number Diff line number Diff line change
@@ -7810,7 +7810,12 @@ def _clone_dataset_or_view(dataset_or_view, name, persistent):

dataset._reload()

_id = ObjectId()
#
# Clone dataset document
#

dataset_doc = dataset._doc.copy(new_id=True)
_id = dataset_doc.id

sample_collection_name = _make_sample_collection_name(_id)

@@ -7821,13 +7826,6 @@ def _clone_dataset_or_view(dataset_or_view, name, persistent):
else:
frame_collection_name = None

#
# Clone dataset document
#

dataset_doc = dataset._doc.copy()

dataset_doc.id = _id
dataset_doc.name = name
dataset_doc.slug = slug
dataset_doc.created_at = datetime.utcnow()
@@ -8288,14 +8286,12 @@ def _clone_extras(src_dataset, dst_dataset):


def _clone_reference_doc(ref_doc):
_ref_doc = ref_doc.copy()
_ref_doc.id = ObjectId()
_ref_doc = ref_doc.copy(new_id=True)
return _ref_doc


def _clone_run(run_doc):
_run_doc = run_doc.copy()
_run_doc.id = ObjectId()
_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...
19 changes: 19 additions & 0 deletions fiftyone/core/odm/document.py
Original file line number Diff line number Diff line change
@@ -583,6 +583,25 @@ class Document(BaseDocument, mongoengine.Document):
def _doc_name(cls):
return "Document"

def copy(self, new_id=False):
"""Returns a deep copy of the document.
Args:
new_id (False): whether to generate a new ID for the copied
document. By default, the ID is left as ``None`` and will be
automatically populated when the document is added to the
database
"""
doc_copy = super().copy()

if new_id:
# pylint: disable=no-member
id_field = self._meta.get("id_field", "id")
doc_copy.set_field(id_field, ObjectId())
doc_copy._created = True

return doc_copy

def reload(self, *fields, **kwargs):
"""Reloads the document from the database.
28 changes: 28 additions & 0 deletions tests/unittests/odm_tests.py
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
from bson import ObjectId

import fiftyone as fo
import fiftyone.core.odm as foo


class ColorSchemeTests(unittest.TestCase):
@@ -29,3 +30,30 @@ def test_color_scheme_serialization(self):

self.assertIsInstance(d["_id"], dict)
assert color_scheme == also_color_scheme


class DocumentTests(unittest.TestCase):
def test_doc_copy_with_new_id(self):
dataset_doc = foo.DatasetDocument(
name="unique",
slug="unique",
sample_collection_name="samples.unique",
version="51.51",
)

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)

finally:
dataset_doc.delete()

0 comments on commit 8811fd9

Please sign in to comment.