I have a Contract
class, that is composed of lists of pages and paragraphs. The pages and paragraphs are defined as separate EmbeddedDocument
classes. (Note that a Paragraph
can span multiple pages, so can not be a child of Page
)
Each Page
and Paragraph
, in turn, have a list of Line
objects. A line will be simultaneously in a page and in a paragraph.
The structure of the classes is as follows:
class Line(mongoengine.EmbeddedDocument):
_id = mongoengine.ObjectIdField(required=True, default=ObjectId)
text = mongoengine.StringField()
class Page(mongoengine.EmbeddedDocument):
lines = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Line))
class Paragraph(mongoengine.EmbeddedDocument):
lines = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Line))
class Contract(mongoengine.Document):
pages = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Page))
paragraphs = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Paragraph))
When I create a new contract and add a line to both the first page and paragraph, the line is one single object. This can be seen below:
# create a new contract
contract = Contract()
# create a new line
line = Line()
line.text = 'This is a test'
# create a new page and add the new line
page = Page()
page.lines.append(line)
contract.pages.append(page)
# create a new paragraph and add the new line
paragraph = Paragraph()
paragraph.lines.append(line)
contract.paragraphs.append(paragraph)
contract.save()
print(contract.pages[0].lines[0] is contract.paragraphs[0].lines[0])
>> True
print(contract.pages[0].lines[0]._id)
>> 5e7b85ebd3844b44ee1a0c8e
print(contract.paragraphs[0].lines[0]._id)
>> 5e7b85ebd3844b44ee1a0c8e
The problem is that after I save the Contract
object to MongoDB
and then load it again in python, the line objects are no longer the same. They still have the same _id
, but if I test for equality, now it returns False:
print(contract.pages[0].lines[0] is contract.paragraphs[0].lines[0])
>> False
print(contract.pages[0].lines[0]._id)
>> 5e7b85ebd3844b44ee1a0c8e
print(contract.paragraphs[0].lines[0]._id)
>> 5e7b85ebd3844b44ee1a0c8e
This is a problem, because when I now update the Line
under Page
, the change will not be reflected in Paragraph
.
Is there a way to ensure that Python/MongoEngine understand that the line is the same?
I'm running Python 3.6, mongoengine 0.19.1