Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix create/drop indexes in every migration #377

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Fix configuration file reading error when containing Chinese characters. (#286)
- sqlite: failed to create/drop index. (#302)
- PostgreSQL: Cannot drop constraint after deleting or rename FK on a model. (#378)
- Fix create/drop indexes in every migration. (#377)
- Sort m2m fields before comparing them with diff. (#271)

#### Changed
Expand Down
27 changes: 13 additions & 14 deletions aerich/migrate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import hashlib
from __future__ import annotations

import importlib
import os
from datetime import datetime
Expand Down Expand Up @@ -197,21 +198,19 @@ def _add_operator(cls, operator: str, upgrade=True, fk_m2m_index=False) -> None:

@classmethod
def _handle_indexes(cls, model: Type[Model], indexes: List[Union[Tuple[str], Index]]) -> list:
ret: list = []
if index_classes := set(index.__class__ for index in indexes if isinstance(index, Index)):
for index_cls in index_classes:
if index_cls(fields=("id",)) != index_cls(fields=("id",)):

def index_hash(self) -> str:
h = hashlib.new("MD5", usedforsecurity=False) # type:ignore[call-arg]
h.update(
self.index_name(cls.ddl.schema_generator, model).encode()
+ self.__class__.__name__.encode()
)
return h.hexdigest()
def _hash(self) -> int:
return hash((tuple(sorted(self.fields)), self.name, self.expressions))

for index in indexes:
if isinstance(index, Index):
index.__hash__ = index_hash # type:ignore[method-assign,assignment]
ret.append(index)
return ret
def _eq(self, other) -> bool:
return type(self) is type(other) and self.__dict__ == other.__dict__

setattr(index_cls, "__hash__", _hash)
setattr(index_cls, "__eq__", _eq)
return indexes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are setting the lower boundary on the tortoise version in #388. Why not just implement __eq__ and __hash__ in Tortoise and set the corresponding version boundary. You won't have to have this hacky code then.


@classmethod
def _get_indexes(cls, model, model_describe: dict) -> Set[Union[Index, Tuple[str, ...]]]:
Expand Down
7 changes: 7 additions & 0 deletions tests/indexes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from tortoise.indexes import Index


class CustomIndex(Index):
def __init__(self, *args, **kw) -> None:
super().__init__(*args, **kw)
self._foo = ""
7 changes: 7 additions & 0 deletions tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
from enum import IntEnum

from tortoise import Model, fields
from tortoise.indexes import Index

from tests.indexes import CustomIndex


class ProductType(IntEnum):
Expand Down Expand Up @@ -33,6 +36,10 @@ class User(Model):

products: fields.ManyToManyRelation["Product"]

class Meta:
# reverse indexes elements
indexes = [CustomIndex(fields=("is_superuser",)), Index(fields=("username", "is_active"))]


class Email(Model):
email_id = fields.IntField(primary_key=True)
Expand Down
6 changes: 6 additions & 0 deletions tests/old_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
from enum import IntEnum

from tortoise import Model, fields
from tortoise.indexes import Index

from tests.indexes import CustomIndex


class ProductType(IntEnum):
Expand Down Expand Up @@ -31,6 +34,9 @@ class User(Model):
intro = fields.TextField(default="")
longitude = fields.DecimalField(max_digits=12, decimal_places=9)

class Meta:
indexes = [Index(fields=("username", "is_active")), CustomIndex(fields=("is_superuser",))]


class Email(Model):
email = fields.CharField(max_length=200)
Expand Down
4 changes: 3 additions & 1 deletion tests/test_migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import pytest
import tortoise
from pytest_mock import MockerFixture
from tortoise.indexes import Index

from aerich.ddl.mysql import MysqlDDL
from aerich.ddl.postgres import PostgresDDL
from aerich.ddl.sqlite import SqliteDDL
from aerich.exceptions import NotSupportError
from aerich.migrate import MIGRATE_TEMPLATE, Migrate
from aerich.utils import get_models_describe
from tests.indexes import CustomIndex

# tortoise-orm>=0.21 changes IntField constraints
# from {"ge": 1, "le": 2147483647} to {"ge": -2147483648, "le": 2147483647}
Expand Down Expand Up @@ -567,7 +569,7 @@
"description": None,
"docstring": None,
"unique_together": [],
"indexes": [],
"indexes": [Index(fields=("username", "is_active")), CustomIndex(fields=("is_superuser",))],
"pk_field": {
"name": "id",
"field_type": "IntField",
Expand Down
Loading