если значение уже существует в mongodb, удалите его, в противном случае добавьте его в конец списка (mongoengine) - PullRequest
0 голосов
/ 25 апреля 2020

Я использую Mongoengine и хочу удалить тег, если он существует. Если тег не существует, я хочу добавить его. Но мой код на самом деле не работает.

    try:

        Project.objects.filter(literature__oid=id).update_one(
            pull__literature__S__tags=tag_name)
        print("wanna delete "+tag_name)

    except:
        Project.objects.filter(literature__oid=id).update_one(
            push__literature__S__tags=tag_name)
        print("wanna add"+tag_name)

этот код только удаляет тег из базы данных, но он не попадает в исключающую часть, если тег не существует. Поэтому он всегда запускает удаление, даже если тег не существует. Есть ли другой метод, который я мог бы использовать? Пока я ничего не нашел ...

поле тегов литературы - это ListField. Например, теги в mongoDB выглядят так:

"tags": ["irrelevant", "relevant", "test"]

Мои модели в основном выглядят так:

class Literature(EmbeddedDocument):
    oid = ObjectIdField(required=True, default=ObjectId,
                        unique=True, primary_key=True, sparse=True)
    tags = ListField() 

class Project(Document):
    project_name = StringField(unique=True, required=True)
    literature = ListField(EmbeddedDocumentField(Literature))

Спасибо

1 Ответ

1 голос
/ 02 мая 2020

Я предпочитаю, чтобы вы не использовали try и except. Вы только go в except, когда ваш блок try вызывает ошибку. Это не вызовет ошибку в вашем случае. Вы можете попытаться написать свой код, проверив, существует ли тег.

Что касается вашей схемы, ваши теги являются списком, но они также являются строками, поэтому я предпочту написать это следующим образом:

class Literature(Document):
    oid = ObjectIdField(required=True, default=ObjectId,
                        unique=True, primary_key=True, sparse=True)
    tags = ListField(StringField()) 

class Project(Document):
    project_name = StringField(unique=True, required=True)
    literature = ListField(ReferenceField("Literature"))

И ваша литературная переменная в Project ссылается на документ Literature, который будет содержать object_id, на который ссылается литература. Затем я напишу свой запрос как таковой, если вы ищете имя тега:

for p in Project.objects():
     if p['literature'] and id in p['literature']:
              lit=Literature.objects(pk=id).first()
              if tag_name in lit['tags']:
                 lit.update_one(pull__tags=tag_name)
              else:
                 lit.update_one(push__tags=tag_name)
              lit.save()
...