WedX - журнал о программировании и компьютерных науках

Mongoengine EmbeddedDocumentListField // Я могу получить доступ только к методу get

Я создаю базу данных для моей школы. Существует студенческий документ с полем EmbeddedDocumentListField для взрослых. Я пытаюсь обновить существующие EmbeddedDocuments, используя методы EmbeddedDocumentListField, но как save(), так и update() дают мне ошибки. get(), похоже, работает.

class Adult(EmbeddedDocument):
    relation = StringField() # Adult, Mother, Father, Grandmother...
    ...
    notes = StringField()

class Student(Document):
    afname = StringField()
    alname = StringField()
    ...
    adults = EmbeddedDocumentListField('Adult')

Я могу успешно использовать метод get

@app.route('/editadult/<aeriesid>/<adultoid>')
def editadult(aeriesid,adultoid):
    editUser = User.objects.get(aeriesid=aeriesid)
    editAdult = editUser.adults.get(oid=adultoid)

Это возвращает объект с именем editAdult с ожидаемыми атрибутами, но не с методами. Теперь я хочу обновить значения в этом объекте. Я могу видеть методы, которые я хочу вызвать, делая.

dir(editUser.adults)

Но не вижу методов с

dir(editAdult)

Из моего чтения документов я должен быть в состоянии сделать это.

editAdult.update(fname="Juanita", lname="Sanchez")

Это дает ошибку: AttributeError: объект «Взрослый» не имеет атрибута «обновление». Но не могу понять, как использовать методы в этом контексте. Я попытался

editAdult.fname = "Juanita"
editAdult.lname = "Sanchez"
editAdult.save()

Но это дает ошибку: AttributeError: объект «Взрослый» не имеет атрибута «сохранить».

Документация скудная. Mongoengine говорит мне, что такое методы, но без примеров. https://docs.mongoengine.org/apireference.html#embedded-document-querying И GitHub дает хорошие примеры, но я не смог заставить их работать. https://github.com/MongoEngine/mongoengine/pull/826

Я использую Mongoengine 0.20.0

17.06.2020

Ответы:


1

После долгих проб и ошибок я понял это. С этой структурой данных:

class Adult(EmbeddedDocument):
    relation = StringField() # Adult, Mother, Father, Grandmother...
    fname = StringField()
    lname = StringField()
    ...
    notes = StringField()

class Student(Document):
    afname = StringField()
    alname = StringField()
    ...
    adults = EmbeddedDocumentListField('Adult')

Затем я создал этот Flask Route

@app.route('/editadult/<aeriesid>/<adultoid>')
def editadult(aeriesid,adultoid):
    editUser = User.objects.get(aeriesid=aeriesid)
    editAdult = editUser.adults.get(oid=adultoid)

Adultoid — это уникальный идентификатор для взрослого, а aeriesid — это уникальный идентификатор для ученика, поэтому я знаю, что оба они получат ровно одну запись.

Часть, которую я упустил, заключается в том, что, хотя объект editAdult содержит именно те значения, которые мне нужны, он НЕ является EmbeddedDocumentListObject, поэтому он не содержит методов. Таким образом, приведенная выше команда get() является базовым методом get() MongoEngine, а НЕ методом get() из EmbeddedDocumentFieldList. (Я показываю EmbeddedDocumentListField get() ниже)

Вот чего мне не хватало. Вот как вы используете метод update() в EmbeddedDocumentListField.

    editUser.adults.filter(oid=adultoid).update(
        relation = form.relation.data,
        fname = form.fname.data,
        lname = form.lname.data,
        ...
        notes = form.notes.data
    )

Я не уверен, что эта команда обновления обновит все отфильтрованные записи. В моем случае возможно, что будет возвращена только одна запись, потому что я фильтрую по уникальному идентификатору. Затем оказывается, что EmbeddedDocumentListField() update() НЕ сохраняется, как в базовом методе update(), поэтому вам нужно сделать это. Этот факт на самом деле хорошо задокументирован в документации MongoEngine. https://docs.mongoengine.org/apireference.html?highlight=embedded%20documents#embedded-document-querying

editUser.adults.filter(oid=adultoid).save()

Наконец, есть еще один способ выполнить исходную команду get():

editAdult2 = editUser.adults.filter(oid=adultoid).get()

Для полноты картины вот маршрут Flask для удаления записи EmbeddedDocument.

@app.route('/deleteadult/<aeriesid>/<adultoid>')
def deleteadult(aeriesid,adultoid):
    editUser = User.objects.get(aeriesid=aeriesid)
    editAdult = editUser.adults.get(oid=adultoid)
    editUser.adults.filter(oid=adultoid).delete()
    editUser.adults.filter(oid=adultoid).save()

Я надеюсь, что это полезно для других. Процесс изучения этого был безумно трудным и в основном методом проб и ошибок. Я подумываю вернуться к SQLAlchemy. :(

17.06.2020
Новые материалы

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

ИИ в аэрокосмической отрасли
Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


Для любых предложений по сайту: [email protected]