Skip to content

Commit

Permalink
Merge pull request #327 from ar0ne/dev
Browse files Browse the repository at this point in the history
Added an option to generate empty migration file
  • Loading branch information
long2ice authored Jan 18, 2024
2 parents 01264f3 + 2b2e465 commit 4370b5e
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ If `aerich` guesses you are renaming a column, it will ask `Rename {old_column}
`True` to rename column without column drop, or choose `False` to drop the column then create. Note that the latter may
lose data.

If you need to manually write migration, you could generate empty file:

```shell
> aerich migrate --name add_index --empty

Success migrate 1_202326122220101229_add_index.py
```

### Upgrade to latest version

```shell
Expand Down
4 changes: 2 additions & 2 deletions aerich/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ async def inspectdb(self, tables: List[str] = None) -> str:
inspect = cls(connection, tables)
return await inspect.inspect()

async def migrate(self, name: str = "update"):
return await Migrate.migrate(name)
async def migrate(self, name: str = "update", empty: bool = False) -> str:
return await Migrate.migrate(name, empty)

async def init_db(self, safe: bool):
location = self.location
Expand Down
1 change: 1 addition & 0 deletions aerich/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ async def cli(ctx: Context, config, app):

@cli.command(help="Generate migrate changes file.")
@click.option("--name", default="update", show_default=True, help="Migrate name.")
@click.option("--empty", default=False, is_flag=True, help="Generate empty migration file.")
@click.pass_context
@coro
async def migrate(ctx: Context, name):
Expand Down
28 changes: 22 additions & 6 deletions aerich/migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,23 @@ async def _generate_diff_py(cls, name):
os.unlink(Path(cls.migrate_location, version_file))

version_file = Path(cls.migrate_location, version)
content = MIGRATE_TEMPLATE.format(
upgrade_sql=";\n ".join(cls.upgrade_operators) + ";",
downgrade_sql=";\n ".join(cls.downgrade_operators) + ";",
)
content = cls._get_diff_file_content()

with open(version_file, "w", encoding="utf-8") as f:
f.write(content)
return version

@classmethod
async def migrate(cls, name) -> str:
async def migrate(cls, name: str, empty: bool) -> str:
"""
diff old models and new models to generate diff content
:param name:
:param name: str name for migration
:param empty: bool if True generates empty migration
:return:
"""
if empty:
return await cls._generate_diff_py(name)

new_version_content = get_models_describe(cls.app)
cls.diff_models(cls._last_version_content, new_version_content)
cls.diff_models(new_version_content, cls._last_version_content, False)
Expand All @@ -147,6 +148,21 @@ async def migrate(cls, name) -> str:

return await cls._generate_diff_py(name)

@classmethod
def _get_diff_file_content(cls) -> str:
"""
builds content for diff file from template
"""
def join_lines(lines: List[str]) -> str:
if not lines:
return ""
return ";\n ".join(lines) + ";"

return MIGRATE_TEMPLATE.format(
upgrade_sql=join_lines(cls.upgrade_operators),
downgrade_sql=join_lines(cls.downgrade_operators)
)

@classmethod
def _add_operator(cls, operator: str, upgrade=True, fk_m2m_index=False):
"""
Expand Down
17 changes: 16 additions & 1 deletion tests/test_migrate.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import tempfile
from pathlib import Path

import pytest
from pytest_mock import MockerFixture

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
from aerich.migrate import MIGRATE_TEMPLATE, Migrate
from aerich.utils import get_models_describe

old_models_describe = {
Expand Down Expand Up @@ -966,3 +969,15 @@ def test_sort_all_version_files(mocker):
"10_datetime_update.py",
"11_datetime_update.py",
]

async def test_empty_migration(mocker) -> None:
mocker.patch("os.listdir", return_value=[])
Migrate.app = "foo"
expected_content = MIGRATE_TEMPLATE.format(upgrade_sql="", downgrade_sql="")
with tempfile.TemporaryDirectory() as temp_dir:
Migrate.migrate_location = temp_dir

migration_file = await Migrate.migrate("update", True)

with open(Path(temp_dir, migration_file), "r") as f:
assert f.read() == expected_content

0 comments on commit 4370b5e

Please sign in to comment.