Это действительно абсурдно, как у mongoengine такая загадочная документация. Я пытаюсь сделать простой (обновить, если существует запрос) на основе нескольких столбцов/полей. Что я подразумеваю под этим
if fieldA has valueA and
fieldB has valueB and
fieldC has valueC
then
update fieldD with newValueD,
fieldE with newValueE
Я мог бы сделать это в методе, упомянутом ниже, но я почти уверен, что существует действительно простой синтаксис upsert, где, если я упомяну поля и значения, он сопоставляет их во всей коллекции, обновляет, если они совпадают, и вставляет, если они не совпадают
def __generateRemoteData(data):
"""
Utils function to add remote data to Mongo
"""
for datum in data:
query = RemoteGraph.objects(
Q(fieldA=datum.get('fieldA')) and
Q(fieldB=datum.get('fieldB')) and
Q(fieldC=datum.get('fieldC')) and
Q(fieldD=datum.get('fieldD')) and
Q(fieldE=datum.get('fieldE')) and
Q(date=datum.get('date'))
)
if not query:
RemoteGraph(
fieldA=datum.get('fieldA'),
fieldB=datum.get('fieldB'),
fieldC=datum.get('fieldC'),
fieldD=datum.get('fieldD'),
fieldE=datum.get('fieldE'),
date=datum.get('date'),
fieldF=datum.get('fieldF'),
fieldG=datum.get('fieldG'),
).save()
else:
query.update(
set__fieldF=datum.get('fieldF'),
set__fieldG=datum.get('fieldG'),
)
Ищите более питонический способ сделать это.
Я изучил upsert
, insert
, modify
, save
, update
, update_one
Во-первых, Q() сочетается только с побитовыми операторами. А смысл Q заключается в объединении операторов &
и |
. Подробный здесь
Существует специальная опция upsert=True
метода QuerySet::update
. Upsert — принудительно вставить новый документ, если RemoteGraph.objects(a=val_a, b=val_b, c=val_c, date=date)
не находит ни одного документа.
RemoteGraph.objects(
a=val_a, b=val_b, c=val_c, date=date
).update(
a=val_a, b=val_b, c=val_c, date=date
)
Также есть метод [QuerySet::modify][3]
и QuerySet::update_one
, они тоже могут добавить новый документ, но в отличие от QuerySet::update
, они будут обновлять только первый документ из QuerySet
.
И, наконец, QuerySet::upsert_one
. Имя говорит само за себя. Одно заметное отличие: вызывает исключение, если QuerySet содержит более одного документа. На самом деле QuerySet::update_one
и QuerySet::upsert_one
— это маленькие обертки над QuerySet::update
.