Skip to content

Support for custom code for non-trivial migrations #4

@merlinz01

Description

@merlinz01

Good to see someone working on this!

In addition to that aerich migrations are db-specific, one of my reasons for opening tortoise/aerich#366 is that aerich doesn't support custom migration code. So I want to make sure that it is on the table for this project.

One real-life example of where custom code would be useful: replacing an "issue_status" enum field with an "issue_open" boolean field. Supposing we have a list of issues where some are open and some are closed. Merely removing the "issue_status" field and adding the "issue_open" field with a default results in data loss, because all the issue statuses are now the default for the added column.
We could improve this with some custom code like this:

class Migration:
    async def before_migrate(self, db):
        self.issues = await db.execute('SELECT id, issue_status FROM issues').all()

    async def after_migrate(self, db):
        for id, old_issue_status in self.issues:
            await db.execute('UPDATE issues SET issue_open=$1 WHERE id=$2', old_issue_status==IssueStatus.CLOSED, id)

Alternatively, (more flexible but maybe too complex):

class Migration:
    operations = [
        CustomFunction('get_old_issue_statuses'),
        RemoveField(...),
        AddField(...),
        CustomFunction('update_new_issue_statuses'),
    ]

    async def get_old_issue_statuses(self, db):
        self.issues = await db.execute('SELECT id, issue_status FROM issues').all()

    async def update_new_issue_statuses(self, db):
        for id, old_issue_status in self.issues:
            await db.execute('UPDATE issues SET issue_open=$1 WHERE id=$2', old_issue_status==IssueStatus.CLOSED, id)

Another thing to consider is optional support for downgrading with custom code, maybe with additional before/after_unmigrate methods or a second argument for CustomFunction.

I'm not really familiar with other migration tools so I don't know if there are any established paradigms for this, but I think we have the opportunity to take Tortoise ORM migrations to the next level.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions