tortoise / aerich

A database migrations tool for TortoiseORM, ready to production.
https://github.com/tortoise/aerich
Apache License 2.0
804 stars 90 forks source link

Aerich creates invalid downgrade SQL string #263

Closed julius425 closed 1 year ago

julius425 commented 1 year ago

aerich==0.7.0 tortoise-orm==0.17.6

my model:

class User(CoreModel):

    email = fields.CharField(100, unique=True, index=True)
    password = fields.CharField(128)
    name = fields.CharField(50)
    surname = fields.CharField(10)
    city = fields.CharField(30, null=True)
    company_name = fields.CharField(40, null=True)
    company_name2 = fields.CharField(40, null=True)
    company_name3 = fields.CharField(40, null=True)

aerich inits and creates field change migration normaly, but downgrade function seems invalid with stacking quotes:

async def upgrade(db: BaseDBAsyncClient) -> List[str]:
    return [
        """ALTER TABLE "user" ADD "company_name3" VARCHAR(40)"""
    ]

async def downgrade(db: BaseDBAsyncClient) -> List[str]:
    return [
        """ALTER TABLE "user" DROP COLUMN "company_name3""""
    ]

and i get this while trying to upgrade:

Traceback (most recent call last):
  File "/usr/local/bin/aerich", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.9/site-packages/aerich/cli.py", line 258, in main
    cli()
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/click/decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/aerich/cli.py", line 31, in wrapper
    loop.run_until_complete(f(*args, **kwargs))
  File "/usr/local/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.9/site-packages/aerich/cli.py", line 97, in upgrade
    migrated = await command.upgrade()
  File "/usr/local/lib/python3.9/site-packages/aerich/__init__.py", line 51, in upgrade
    m = import_py_file(file_path)
  File "/usr/local/lib/python3.9/site-packages/aerich/utils.py", line 101, in import_py_file
    spec.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 846, in exec_module
  File "<frozen importlib._bootstrap_external>", line 983, in get_code
  File "<frozen importlib._bootstrap_external>", line 913, in source_to_code
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "migrations/models/2_20220923120735_update.py", line 8
    """ALTER TABLE "user" DROP COLUMN "company_name3"""",
                                                   ^
SyntaxError: EOL while scanning string literal
long2ice commented 1 year ago

fixed

louison commented 1 year ago

Juste tried 0.7.1rc1 and it seems it is still broken:

For the give model class:

class Signature(DBObject):
    label = fields.ForeignKeyField("models.Label", to_field="id",
                                   related_name="label_signatures")
    owner = fields.ForeignKeyField("models.Player", to_field="id",
                                   related_name="player_signatures")
    league = fields.ForeignKeyField('models.League',
                                    related_name='league_signatures')
    artist_id = fields.CharField(max_length=255)
    advance = fields.IntField()
    is_active = fields.BooleanField()

aerich generates the following in 0.7.0:

from typing import List

from tortoise import BaseDBAsyncClient

async def upgrade(db: BaseDBAsyncClient) -> List[str]:
    return [
        """CREATE TABLE IF NOT EXISTS "signature" (
    "id" UUID NOT NULL  PRIMARY KEY,
    "created_at" TIMESTAMPTZ NOT NULL  DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMPTZ NOT NULL  DEFAULT CURRENT_TIMESTAMP,
    "artist_id" VARCHAR(255) NOT NULL,
    "advance" INT NOT NULL,
    "is_active" BOOL NOT NULL,
    "label_id" UUID NOT NULL REFERENCES "label" ("id") ON DELETE CASCADE,
    "league_id" UUID NOT NULL REFERENCES "league" ("id") ON DELETE CASCADE,
    "owner_id" VARCHAR(50) NOT NULL REFERENCES "player" ("id") ON DELETE CASCADE
);"""
    ]

async def downgrade(db: BaseDBAsyncClient) -> List[str]:
    return [
        """DROP TABLE IF EXISTS "signature""""
    ]

And the following in 0.7.1rc1:

from typing import List

from tortoise import BaseDBAsyncClient

async def upgrade(db: BaseDBAsyncClient) -> List[str]:
    return [
        'CREATE TABLE IF NOT EXISTS "signature" (
    "id" UUID NOT NULL  PRIMARY KEY,
    "created_at" TIMESTAMPTZ NOT NULL  DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMPTZ NOT NULL  DEFAULT CURRENT_TIMESTAMP,
    "artist_id" VARCHAR(255) NOT NULL,
    "advance" INT NOT NULL,
    "is_active" BOOL NOT NULL,
    "label_id" UUID NOT NULL REFERENCES "label" ("id") ON DELETE CASCADE,
    "league_id" UUID NOT NULL REFERENCES "league" ("id") ON DELETE CASCADE,
    "owner_id" VARCHAR(50) NOT NULL REFERENCES "player" ("id") ON DELETE CASCADE
);'
    ]

async def downgrade(db: BaseDBAsyncClient) -> List[str]:
    return [
        'DROP TABLE IF EXISTS "signature"'
    ]

And when I try to apply the migration I have the following error:

    'CREATE TABLE IF NOT EXISTS "signature" (
    ^
SyntaxError: unterminated string literal (detected at line 8)
long2ice commented 1 year ago

Try latest source again