Документ MongoEngine, встроенный в несколько документов, не совпадает - PullRequest
2 голосов
/ 25 марта 2020

У меня есть класс Contract, который состоит из списков страниц и абзацев. Страницы и абзацы определены как отдельные EmbeddedDocument классы. (Обратите внимание, что Paragraph может занимать несколько страниц, поэтому не может быть дочерним по отношению к Page)

Каждый Page и Paragraph, в свою очередь, имеют список Line объектов. Строка будет одновременно на странице и в абзаце.

Структура классов выглядит следующим образом:

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))

Когда я создаю новый контракт и добавляю строку к обоим Первая страница и абзац, строка - это один объект. Это можно увидеть ниже:

# 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

Проблема в том, что после сохранения объекта Contract в MongoDB и последующей его загрузки в python линейные объекты больше не совпадают. Они по-прежнему имеют тот же _id, но если я проверю на равенство, теперь он возвращает 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

Это проблема, потому что когда я сейчас обновляю Line в Page, изменение не будет отражено в Paragraph.

Есть ли способ гарантировать, что Python / MongoEngine поймет, что линия одинакова?

Я работаю Python 3.6, mongoengine 0.19.1

1 Ответ

0 голосов
/ 25 марта 2020

is вернет True, если две переменные указывают на один и тот же объект, ==, если объекты, на которые ссылаются переменные, равны.

Есть ли разница между "==" и "is"?

Изменить на:

print(contract.pages[0].lines[0] == contract.paragraphs[0].lines[0])

Пояснение

Перед сохранением contract экземпляр, pages и paragraphs имели одинаковый экземпляр строк.

После сохранения pymongo сериализует ваш объект в структуру BSON.

После извлечения из MongoDB python создаст новые экземпляры для pages и paragraphs из структуры BSON (десериализация)

...