Suppose I have a collection of documents defined with MongoEngine as:
class Project(Document):
name = StringField(required=True)
client = StringField(required=True)
code = StringField(required=True,unique=True)
created = DateTimeField(required=True,default=datetime.datetime.now)
Historically, I could have used the get_or_create
method to perform an "insert or update" type operation. For example:
Project.objects().get_or_create(name="Test Project One",
client="Client One",
code="CL1-001")
Which adds the following document to the collection:
{
"name": "Test Project One",
"client": "Client One",
"code": "CL1-001",
"created": {
"$date": "2014-07-14T14:00:38.024Z"
}
}
Now that this method has been depreciated the recommend alternative is to use update_one
with upsert=True
as follows:
Project.objects(code="CL1-002").update_one(set__name="Test Project Two",
set__client="Client One",
upsert=True)
But this results in a document being added to the collection without the created
field:
{
"client": "Client One",
"code": "CL1-002",
"name": "Test Project Two"
}
Is there is any way to replicate the get_or_create
default field behaviour with MongoEngine without a race condition?
This currently isn't supported automatically but it could be - please add a ticket and the maintainers can review.
In the meantime you can use $setOnInsert which only sets a value if it inserts and that will replicate whats needed eg:
Project.objects(code="CL1-002").update_one(set_on_insert__created=Project().created,
set__name="Test Project Two",
set__client="Client One",
upsert=True)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With