diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fc071e..651b918 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # ChangeLog +## 0.3 + +### 0.3.0 + +- Refactoring migrate logic, and this version is not compatible with previous version. +- Now there don't need `old_models.py` and it store in database. +- Upgrade steps: + 1. Upgrade aerich version. + 2. Drop aerich model in db and recreate with new struct. + 3. Delete `migrations/{app}` folder and rerun `aerich init-db`. + 4. Update model and `aerich migrate` normally. + ## 0.2 ### 0.2.5 diff --git a/README.md b/README.md index 30de17b..fe58f77 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,19 @@ Success upgrade 1_202029051520102929_drop_column.json Now your db is migrated to latest. -### Downgrade to previous version +### Downgrade to specified version + +```shell +$ aerich init -h + +Usage: aerich downgrade [OPTIONS] + + Downgrade to specified version. + +Options: + -v, --version INTEGER Specified version, default to last. [default: -1] + -h, --help Show this message and exit. +``` ```shell $ aerich downgrade @@ -133,7 +145,7 @@ $ aerich downgrade Success downgrade 1_202029051520102929_drop_column.json ``` -Now your db rollback to previous version. +Now your db rollback to specified version. ### Show history diff --git a/aerich/__init__.py b/aerich/__init__.py index 01ef120..493f741 100644 --- a/aerich/__init__.py +++ b/aerich/__init__.py @@ -1 +1 @@ -__version__ = "0.2.6" +__version__ = "0.3.0" diff --git a/aerich/cli.py b/aerich/cli.py index ddcde9e..a236ea1 100644 --- a/aerich/cli.py +++ b/aerich/cli.py @@ -79,10 +79,6 @@ async def cli(ctx: Context, config, app, name): @click.pass_context @coro async def migrate(ctx: Context, name): - config = ctx.obj["config"] - location = ctx.obj["location"] - app = ctx.obj["app"] - ret = await Migrate.migrate(name) if not ret: return click.secho("No changes detected", fg=Color.yellow) @@ -90,16 +86,9 @@ async def migrate(ctx: Context, name): @cli.command(help="Upgrade to specified version.") -@click.option( - "--version", - default=-1, - type=int, - show_default=True, - help="Specified version, default to latest.", -) @click.pass_context @coro -async def upgrade(ctx: Context, version: int): +async def upgrade(ctx: Context): config = ctx.obj["config"] app = ctx.obj["app"] location = ctx.obj["location"] @@ -124,15 +113,18 @@ async def upgrade(ctx: Context, version: int): ) click.secho(f"Success upgrade {version_file}", fg=Color.green) migrated = True - if version != -1 and version_file.startswith(str(version)): - break if not migrated: click.secho("No migrate items", fg=Color.yellow) @cli.command(help="Downgrade to specified version.") @click.option( - "--version", default=-1, type=int, show_default=True, help="Specified version, default to last." + "-v", + "--version", + default=-1, + type=int, + show_default=True, + help="Specified version, default to last.", ) @click.pass_context @coro @@ -142,22 +134,27 @@ async def downgrade(ctx: Context, version: int): if version == -1: specified_version = await Migrate.get_last_version() else: - specified_version = await Aerich.filter(app=app, pk=version + 1).first() + specified_version = await Aerich.filter(app=app, version__startswith=f"{version}_").first() if not specified_version: return click.secho("No specified version found", fg=Color.yellow) - file = specified_version.version - async with in_transaction(get_app_connection_name(config, app)) as conn: - file_path = os.path.join(Migrate.migrate_location, file) - with open(file_path, "r", encoding="utf-8") as f: - content = json.load(f) - downgrade_query_list = content.get("downgrade") - if not downgrade_query_list: - return click.secho("No downgrade item found", fg=Color.yellow) - for downgrade_query in downgrade_query_list: - await conn.execute_query(downgrade_query) - await specified_version.delete() - os.unlink(file_path) - return click.secho(f"Success downgrade {file}", fg=Color.green) + if version == -1: + versions = [specified_version] + else: + versions = await Aerich.filter(app=app, pk__gte=specified_version.pk) + for version in versions: + file = version.version + async with in_transaction(get_app_connection_name(config, app)) as conn: + file_path = os.path.join(Migrate.migrate_location, file) + with open(file_path, "r", encoding="utf-8") as f: + content = json.load(f) + downgrade_query_list = content.get("downgrade") + if not downgrade_query_list: + return click.secho("No downgrade item found", fg=Color.yellow) + for downgrade_query in downgrade_query_list: + await conn.execute_query(downgrade_query) + await version.delete() + os.unlink(file_path) + click.secho(f"Success downgrade {file}", fg=Color.green) @cli.command(help="Show current available heads in migrate location.") diff --git a/aerich/ddl/sqlite/__init__.py b/aerich/ddl/sqlite/__init__.py index 3b3eca8..ee66618 100644 --- a/aerich/ddl/sqlite/__init__.py +++ b/aerich/ddl/sqlite/__init__.py @@ -13,7 +13,7 @@ class SqliteDDL(BaseDDL): DIALECT = SqliteSchemaGenerator.DIALECT def drop_column(self, model: "Type[Model]", column_name: str): - raise NotSupportError("Drop column is not support in SQLite.") + raise NotSupportError("Drop column is unsupported in SQLite.") def modify_column(self, model: "Type[Model]", field_object: Field): - raise NotSupportError("Modify column is not support in SQLite.") + raise NotSupportError("Modify column is unsupported in SQLite.") diff --git a/aerich/exceptions.py b/aerich/exceptions.py index 468865c..a9272ec 100644 --- a/aerich/exceptions.py +++ b/aerich/exceptions.py @@ -2,9 +2,3 @@ class NotSupportError(Exception): """ raise when features not support """ - - -class DuplicationError(Exception): - """ - raise when something duplication - """ diff --git a/aerich/migrate.py b/aerich/migrate.py index c9c409f..a35cd26 100644 --- a/aerich/migrate.py +++ b/aerich/migrate.py @@ -115,6 +115,10 @@ class Migrate: @classmethod async def _generate_diff_sql(cls, name): version = await cls.generate_version(name) + # delete if same version exists + for version_file in cls.get_all_version_files(): + if version_file.startswith(version.split("_")[0]): + os.unlink(os.path.join(cls.migrate_location, version_file)) content = { "upgrade": cls.upgrade_operators, "downgrade": cls.downgrade_operators, diff --git a/pyproject.toml b/pyproject.toml index 3549bf1..6e19077 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aerich" -version = "0.2.6" +version = "0.3.0" description = "A database migrations tool for Tortoise ORM." authors = ["long2ice "] license = "Apache-2.0"