Skip to content

Commit 8811fd9

Browse files
authored
Merge pull request #4729 from voxel51/fix/mongoengine-document-misc-bugs
fix copied doc updates not insert
2 parents 25bfc40 + 86aad06 commit 8811fd9

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

fiftyone/core/dataset.py

+8-12
Original file line numberDiff line numberDiff line change
@@ -7810,7 +7810,12 @@ def _clone_dataset_or_view(dataset_or_view, name, persistent):
78107810

78117811
dataset._reload()
78127812

7813-
_id = ObjectId()
7813+
#
7814+
# Clone dataset document
7815+
#
7816+
7817+
dataset_doc = dataset._doc.copy(new_id=True)
7818+
_id = dataset_doc.id
78147819

78157820
sample_collection_name = _make_sample_collection_name(_id)
78167821

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

7824-
#
7825-
# Clone dataset document
7826-
#
7827-
7828-
dataset_doc = dataset._doc.copy()
7829-
7830-
dataset_doc.id = _id
78317829
dataset_doc.name = name
78327830
dataset_doc.slug = slug
78337831
dataset_doc.created_at = datetime.utcnow()
@@ -8288,14 +8286,12 @@ def _clone_extras(src_dataset, dst_dataset):
82888286

82898287

82908288
def _clone_reference_doc(ref_doc):
8291-
_ref_doc = ref_doc.copy()
8292-
_ref_doc.id = ObjectId()
8289+
_ref_doc = ref_doc.copy(new_id=True)
82938290
return _ref_doc
82948291

82958292

82968293
def _clone_run(run_doc):
8297-
_run_doc = run_doc.copy()
8298-
_run_doc.id = ObjectId()
8294+
_run_doc = run_doc.copy(new_id=True)
82998295
_run_doc.results = None
83008296

83018297
# Unfortunately the only way to copy GridFS files is to read-write them...

fiftyone/core/odm/document.py

+19
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,25 @@ class Document(BaseDocument, mongoengine.Document):
583583
def _doc_name(cls):
584584
return "Document"
585585

586+
def copy(self, new_id=False):
587+
"""Returns a deep copy of the document.
588+
589+
Args:
590+
new_id (False): whether to generate a new ID for the copied
591+
document. By default, the ID is left as ``None`` and will be
592+
automatically populated when the document is added to the
593+
database
594+
"""
595+
doc_copy = super().copy()
596+
597+
if new_id:
598+
# pylint: disable=no-member
599+
id_field = self._meta.get("id_field", "id")
600+
doc_copy.set_field(id_field, ObjectId())
601+
doc_copy._created = True
602+
603+
return doc_copy
604+
586605
def reload(self, *fields, **kwargs):
587606
"""Reloads the document from the database.
588607

tests/unittests/odm_tests.py

+28
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from bson import ObjectId
1111

1212
import fiftyone as fo
13+
import fiftyone.core.odm as foo
1314

1415

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

3031
self.assertIsInstance(d["_id"], dict)
3132
assert color_scheme == also_color_scheme
33+
34+
35+
class DocumentTests(unittest.TestCase):
36+
def test_doc_copy_with_new_id(self):
37+
dataset_doc = foo.DatasetDocument(
38+
name="unique",
39+
slug="unique",
40+
sample_collection_name="samples.unique",
41+
version="51.51",
42+
)
43+
44+
try:
45+
dataset_doc.save()
46+
47+
# Copy with new ID -- ID should be new, _created should be True
48+
doc_copy = dataset_doc.copy(new_id=True)
49+
self.assertNotEqual(
50+
dataset_doc.get_field("id"), doc_copy.get_field("id")
51+
)
52+
self.assertTrue(doc_copy._created)
53+
54+
# Now if we set ID to be same, the doc should be the same
55+
doc_copy.set_field("id", dataset_doc.get_field("id"))
56+
self.assertEqual(doc_copy, dataset_doc)
57+
58+
finally:
59+
dataset_doc.delete()

0 commit comments

Comments
 (0)