Open
Description
BaseDocument._unique_with_indexes method looks like this:
@classmethod
def _unique_with_indexes(cls, namespace=""):
"""
Find and set unique indexes
"""
unique_indexes = []
for field_name, field in list(cls._fields.items()):
sparse = field.sparse
# Generate a list of indexes needed by uniqueness constraints
if field.unique:
unique_fields = [field.db_field]
# Add any unique_with fields to the back of the index spec
if field.unique_with:
if isinstance(field.unique_with, str):
field.unique_with = [field.unique_with]
# Convert unique_with field names to real field names
unique_with = []
for other_name in field.unique_with:
parts = other_name.split('.')
# Lookup real name
parts = cls._lookup_field(parts)
name_parts = [part.db_field for part in parts]
unique_with.append('.'.join(name_parts))
# Unique field should be required
parts[-1].required = True
sparse = (not sparse and
parts[-1].name not in cls.__dict__)
unique_fields += unique_with
# Add the new index to the list
fields = [("%s%s" % (namespace, f), pymongo.ASCENDING)
for f in unique_fields]
index = {'fields': fields, 'unique': True, 'sparse': sparse}
unique_indexes.append(index)
if field.__class__.__name__ == "ListField":
field = field.field
# Grab any embedded document field unique indexes
if (field.__class__.__name__ == "EmbeddedDocumentField" and
field.document_type != cls):
field_namespace = "%s." % field_name
doc_cls = field.document_type
unique_indexes += doc_cls._unique_with_indexes(field_namespace)
return unique_indexes
And I believe, this part shouldn't be so implicit:
# Unique field should be required
parts[-1].required = True
Because the following document won't work as expected, even though required=False
is explicitly written:
class MongoDocument(Document):
id1 = StringField(required=False, null=True)
id2 = StringField(required=False, null=True, unique_with='id1')
- Why "Unique field should be required"? Unique indexes on nullable fields work like a charm.
- My proposal is as follows: either remove this logic completely or raise an exception if the field isn't declared as
required
explicitly:
if not parts[-1].required:
raise ...