MongoEngine / MongoEngine/mongoengine
`unique` fails if `db_field` is set on an EmbeddedDocument
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 1.2k
- Avg merge
- 4h 41m
- Merged PRs (30d)
- 11
Description
I have been running into various problems when combining db_field=True with pretty much any other MongoEngine features. Today I tried to set unique=True on a string field, only to find out the database would raise a NotUniqueError for any more than a single document per collection.
Here is my example schema:
class Name(EmbeddedDocument):
_first = StringField(db_field='first')
_middle = StringField(db_field='middle')
_last = StringField(db_field='last', required=True)
_full = StringField(db_field='full', required=True, unique=True)
@property
def first(self):
return self._first
# (...)
class Person(Document):
_name = EmbeddedDocumentField(Name, db_field='name',
required=True, default=Name)
_desc = StringField(db_field='desc')
_birth = EmbeddedDocumentField(Year, db_field='birth')
_death = EmbeddedDocumentField(Year, db_field='death')
@property
def name(self):
return self._name
# (...)
If I created a person with the full name "John Doe", that would work fine. Creating a second person with the name "Jimmy Bob" (or any other name), however, raises a NotUniqueError.
Looking at the indexes in MongoDB:
> db.person.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "citeline_dev.person"
},
{
"v" : 1,
"unique" : true,
"key" : {
"_name.full" : 1
},
"name" : "_name.full_1",
"ns" : "citeline_dev.person",
"sparse" : false,
"background" : false
}
]
With that I gathered the field was setting the index name based on the attribute Person._name, which does not match the db_field setting of name.
To work around this issue I modified Person to use a global index:
class Person(Document):
# (...)
meta = {
'indexes': [
{
'fields': ['_name._full'],
'unique': True
}
]
}
# (...)
Note: At first I tried to set the fields to name.full, however, MongoEngine complained that neither name nor field were set.
Please consider fixing the field options so they work out of the box with the db_field option.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No source file or test is named in the issue. Start by reproducing the EmbeddedDocument schema and inspecting the generated MongoDB index; done means a unique field using db_field creates the index on the stored field path and permits distinct values in separate documents.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mongodb, python
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100