MongoEngine delete document
Asked Answered
G

6

6

I have the following MongoEngine document

{
    '_id': 'some_id',
    'data': 'some_data'
}

How can I delete this document using MongoEngine?

What I've tried:

import my_collection

obj = my_collection.MyCol.objects.get(_id='some_id')
# obj is correctly found - let's continue

obj.delete()
# mongoengine.errors.ValidationError: 'None' is not a valid ObjectId

obj.delete('some_id')
# TypeError: delete() takes 1 positional argument but 2 were given

obj.delete(_id='some_id')
# mongoengine.errors.ValidationError: 'None' is not a valid ObjectId

-- note

Oddly enough, the following works perfectly:

my_collection.MyCol.objects.delete()
# delete all documents in the collection

But I've followed MongoEngine docs, and still can't manage to delete just one specific document.

Grout answered 26/5, 2016 at 16:19 Comment(4)
I think that note has something to do with that: Note that this will only work if the document exists in the database and has a valid id.Monosyllabic
@Monosyllabic mmm I thought about this actually, but dismissed it because MongoEngine says 'None' is not a valid ObjectId - not 'some_id'Grout
Posted a current theory as an answer. Do you have a custom primary key/field defined on the model? Thanks.Monosyllabic
@alexce adding primary_key=True in the _id field definition solved the problem - thanks for pointing this outGrout
T
4

If your document overrides _id, you must indicate that it's still the primary key. Change your document class definition from:

class MyCol(Document):
    _id = db.StringField()
    ...

To specify the primary key:

class MyCol(Document):
    _id = db.StringField(primary_key=True)
    ...
Thalassa answered 15/10, 2016 at 18:13 Comment(0)
W
6

When referencing mongoengine ObjecIds you don't use the underscore.

obj = my_collection.MyCol.objects.get(id='some_id')

or

obj = my_collection.MyCol.objects(id='some_id')
obj.delete()
Whinny answered 28/10, 2016 at 22:31 Comment(0)
T
4

If your document overrides _id, you must indicate that it's still the primary key. Change your document class definition from:

class MyCol(Document):
    _id = db.StringField()
    ...

To specify the primary key:

class MyCol(Document):
    _id = db.StringField(primary_key=True)
    ...
Thalassa answered 15/10, 2016 at 18:13 Comment(0)
M
2

From what I understand and according to the note in the docs:

Note that this will only work if the document exists in the database and has a valid id

obj.delete() would only work if the object ID - the obj.id property - has a valid ObjectId value. In your case, you don't have obj.id defined, use the objects.delete() syntax:

my_collection.MyCol.objects.delete()
Monosyllabic answered 26/5, 2016 at 16:33 Comment(0)
E
2

You can delete one specific document using the following command

my_collection.MyCol.objects(id='some_id').delete()
Excrescent answered 6/8, 2018 at 19:18 Comment(0)
H
0

my_collection.MyCol.objects(id='some_id').delete()

Hexose answered 11/8, 2018 at 8:38 Comment(0)
P
0

In my case I forgot to mark the document id as the primary key.

from bson import ObjectId
from conn import db
class ProductModel(db.Document):
    meta = {'collection': 'products'}
    _id = db.ObjectIdField() #throws the exception
    _id = db.ObjectIdField(primary_key=True,default=ObjectId) #correct way to not throw exception

    @classmethod
    def getById(cls, idProduct: str):
        return cls.objects(_id=ObjectId(idProduto)).first()

How to use

#from bson import ObjectId

id = 630a18fb70392af65e9d63bc
if ObjectId.is_valid(id) == False:
    return {'message':'Provide a valid id.'}

ProductModel.getById(idProduct=id).delete()
Prefect answered 27/8, 2022 at 15:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.