fix: no migration occurs when adding unique true to indexed field (#414)
* feat: alter unique for indexed column * chore: update docs and change some var names
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
from collections.abc import Generator
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
|
||||
from aerich.ddl.sqlite import SqliteDDL
|
||||
from aerich.migrate import Migrate
|
||||
from tests._utils import chdir, copy_files
|
||||
from tests._utils import Dialect, chdir, copy_files
|
||||
|
||||
|
||||
def run_aerich(cmd: str) -> None:
|
||||
@@ -22,9 +24,14 @@ def run_shell(cmd: str) -> subprocess.CompletedProcess:
|
||||
return subprocess.run(shlex.split(cmd), env=envs)
|
||||
|
||||
|
||||
def test_sqlite_migrate(tmp_path: Path) -> None:
|
||||
if (ddl := getattr(Migrate, "ddl", None)) and not isinstance(ddl, SqliteDDL):
|
||||
return
|
||||
def _get_empty_db() -> Path:
|
||||
if (db_file := Path("db.sqlite3")).exists():
|
||||
db_file.unlink()
|
||||
return db_file
|
||||
|
||||
|
||||
@contextmanager
|
||||
def prepare_sqlite_project(tmp_path: Path) -> Generator[tuple[Path, str]]:
|
||||
test_dir = Path(__file__).parent
|
||||
asset_dir = test_dir / "assets" / "sqlite_migrate"
|
||||
with chdir(tmp_path):
|
||||
@@ -32,9 +39,52 @@ def test_sqlite_migrate(tmp_path: Path) -> None:
|
||||
copy_files(*(asset_dir / f for f in files), target_dir=Path())
|
||||
models_py, settings_py, test_py = (Path(f) for f in files)
|
||||
copy_files(asset_dir / "conftest_.py", target_dir=Path("conftest.py"))
|
||||
if (db_file := Path("db.sqlite3")).exists():
|
||||
db_file.unlink()
|
||||
MODELS = models_py.read_text("utf-8")
|
||||
_get_empty_db()
|
||||
yield models_py, models_py.read_text("utf-8")
|
||||
|
||||
|
||||
def test_sqlite_migrate_alter_indexed_unique(tmp_path: Path) -> None:
|
||||
if not Dialect.is_sqlite():
|
||||
return
|
||||
with prepare_sqlite_project(tmp_path) as (models_py, models_text):
|
||||
models_py.write_text(models_text.replace("db_index=False", "db_index=True"))
|
||||
run_aerich("aerich init -t settings.TORTOISE_ORM")
|
||||
run_aerich("aerich init-db")
|
||||
r = run_shell("pytest -s _tests.py::test_allow_duplicate")
|
||||
assert r.returncode == 0
|
||||
models_py.write_text(models_text.replace("db_index=False", "unique=True"))
|
||||
run_aerich("aerich migrate") # migrations/models/1_
|
||||
run_aerich("aerich upgrade")
|
||||
r = run_shell("pytest _tests.py::test_unique_is_true")
|
||||
assert r.returncode == 0
|
||||
models_py.write_text(models_text.replace("db_index=False", "db_index=True"))
|
||||
run_aerich("aerich migrate") # migrations/models/2_
|
||||
run_aerich("aerich upgrade")
|
||||
r = run_shell("pytest -s _tests.py::test_allow_duplicate")
|
||||
assert r.returncode == 0
|
||||
|
||||
|
||||
M2M_WITH_CUSTOM_THROUGH = """
|
||||
groups = fields.ManyToManyField("models.Group", through="foo_group")
|
||||
|
||||
class Group(Model):
|
||||
name = fields.CharField(max_length=60)
|
||||
|
||||
class FooGroup(Model):
|
||||
foo = fields.ForeignKeyField("models.Foo")
|
||||
group = fields.ForeignKeyField("models.Group")
|
||||
is_active = fields.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
table = "foo_group"
|
||||
"""
|
||||
|
||||
|
||||
def test_sqlite_migrate(tmp_path: Path) -> None:
|
||||
if not Dialect.is_sqlite():
|
||||
return
|
||||
with prepare_sqlite_project(tmp_path) as (models_py, models_text):
|
||||
MODELS = models_text
|
||||
run_aerich("aerich init -t settings.TORTOISE_ORM")
|
||||
config_file = Path("pyproject.toml")
|
||||
modify_time = config_file.stat().st_mtime
|
||||
@@ -84,7 +134,7 @@ def test_sqlite_migrate(tmp_path: Path) -> None:
|
||||
# Initial with indexed field and then drop it
|
||||
migrations_dir = Path("migrations/models")
|
||||
shutil.rmtree(migrations_dir)
|
||||
db_file.unlink()
|
||||
db_file = _get_empty_db()
|
||||
models_py.write_text(MODELS + " age = fields.IntField(db_index=True)")
|
||||
run_aerich("aerich init -t settings.TORTOISE_ORM")
|
||||
run_aerich("aerich init-db")
|
||||
@@ -119,21 +169,7 @@ def test_sqlite_migrate(tmp_path: Path) -> None:
|
||||
assert "[tool.aerich]" in config_file.read_text()
|
||||
|
||||
# add m2m with custom model for through
|
||||
new = """
|
||||
groups = fields.ManyToManyField("models.Group", through="foo_group")
|
||||
|
||||
class Group(Model):
|
||||
name = fields.CharField(max_length=60)
|
||||
|
||||
class FooGroup(Model):
|
||||
foo = fields.ForeignKeyField("models.Foo")
|
||||
group = fields.ForeignKeyField("models.Group")
|
||||
is_active = fields.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
table = "foo_group"
|
||||
"""
|
||||
models_py.write_text(MODELS + new)
|
||||
models_py.write_text(MODELS + M2M_WITH_CUSTOM_THROUGH)
|
||||
run_aerich("aerich migrate")
|
||||
run_aerich("aerich upgrade")
|
||||
migration_file_1 = list(migrations_dir.glob("1_*.py"))[0]
|
||||
@@ -148,8 +184,7 @@ class FooGroup(Model):
|
||||
class Group(Model):
|
||||
name = fields.CharField(max_length=60)
|
||||
"""
|
||||
if db_file.exists():
|
||||
db_file.unlink()
|
||||
_get_empty_db()
|
||||
if migrations_dir.exists():
|
||||
shutil.rmtree(migrations_dir)
|
||||
models_py.write_text(MODELS)
|
||||
|
||||
Reference in New Issue
Block a user