Skip to content

Commit

Permalink
Merge pull request #147 from mauro-andre/fix_text_index_duplicate
Browse files Browse the repository at this point in the history
🐛 Fix text index duplicate name
  • Loading branch information
mauro-andre authored Oct 7, 2024
2 parents 93e8e0e + 66e33d5 commit 9acc178
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 22 deletions.
1 change: 1 addition & 0 deletions pyodmongo/models/db_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class DbModel(BaseModel, metaclass=DbMeta):
updated_at: datetime | None = None
model_config = ConfigDict(populate_by_name=True)
_pipeline: ClassVar = []
_default_language: ClassVar = None

def __remove_empty_dict(self, dct: dict):
if dct == {}:
Expand Down
2 changes: 1 addition & 1 deletion pyodmongo/models/metaclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,6 @@ def __new__(
) -> type:
cls: BaseModel = PyOdmongoMeta.__new__(cls, name, bases, namespace, **kwargs)

indexes = resolve_indexes(cls=cls, indexes=[], text_keys=[], indexes_path=[], text_indexes_path=[])
indexes = resolve_indexes(cls=cls)
setattr(cls, "_init_indexes", indexes)
return cls
57 changes: 36 additions & 21 deletions pyodmongo/services/model_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,13 @@
from ..services.verify_subclasses import is_subclass


def resolve_indexes(
def __ordinary_index_and_text_keys(
cls: BaseModel,
indexes: list,
text_keys: list,
indexes_path: list,
text_indexes_path: list,
):
"""
Resolves and constructs MongoDB index models for the fields of a given class based on field attributes.
Args:
cls (BaseModel): The model class whose indexes are to be resolved.
Returns:
list[IndexModel]: A list of MongoDB index models constructed for the class fields.
Description:
This method iterates over the model fields and checks for index-related attributes (index, unique,
text_index). It creates appropriate MongoDB index structures (IndexModel) for these fields,
including handling of text indexes and unique constraints.
"""

for key in cls.model_fields.keys():
try:
db_field_info: DbField = getattr(cls, key)
Expand All @@ -38,10 +23,14 @@ def resolve_indexes(
f"The {cls.__name__} class inherits from Pydantic's BaseModel class. Try switching to PyODMongo's MainBaseModel class"
)

if db_field_info.has_model_fields and not db_field_info.by_reference:
if (
db_field_info.has_model_fields
and not db_field_info.by_reference
and not db_field_info.is_list
):
indexes_path.append(db_field_info.field_alias)
text_indexes_path.append(db_field_info.field_alias)
resolve_indexes(
__ordinary_index_and_text_keys(
cls=db_field_info.field_type,
indexes=indexes,
text_keys=text_keys,
Expand All @@ -56,9 +45,6 @@ def resolve_indexes(
is_text_index = (
cls.model_fields[key].json_schema_extra.get("text_index") or False
)
default_language = (
cls.model_fields[key].json_schema_extra.get("default_language") or False
)
if is_index:
indexes_path.append(db_field_info.field_alias)
index_name = ".".join(indexes_path)
Expand All @@ -71,8 +57,37 @@ def resolve_indexes(
text_index_name = ".".join(text_indexes_path)
text_keys.append((text_index_name, TEXT))
text_indexes_path.pop()
return indexes, text_keys


def resolve_indexes(cls: BaseModel):
"""
Resolves and constructs MongoDB index models for the fields of a given class based on field attributes.
Args:
cls (BaseModel): The model class whose indexes are to be resolved.
Returns:
list[IndexModel]: A list of MongoDB index models constructed for the class fields.
Description:
This method iterates over the model fields and checks for index-related attributes (index, unique,
text_index). It creates appropriate MongoDB index structures (IndexModel) for these fields,
including handling of text indexes and unique constraints.
"""
indexes = []
text_keys = []

indexes, text_keys = __ordinary_index_and_text_keys(
cls=cls,
indexes=indexes,
text_keys=text_keys,
indexes_path=[],
text_indexes_path=[],
)

if len(text_keys) > 0:
default_language = cls._default_language
if default_language:
indexes.append(
IndexModel(text_keys, name="texts", default_language=default_language)
Expand Down
1 change: 1 addition & 0 deletions tests/test_db_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class MyClass(DbModel):
attr_3: str = Field(text_index=True)
attr_4: str = Field(index=True, text_index=True, default_language="portuguese")
_collection: ClassVar = "my_class"
_default_language: ClassVar = "portuguese"


class MyClass2(DbModel):
Expand Down

0 comments on commit 9acc178

Please sign in to comment.