aerich icon indicating copy to clipboard operation
aerich copied to clipboard

Wrong content field in Aerich table when running "aerich upgrade" with modified models

Open chobeat opened this issue 1 year ago • 2 comments

I've spotted a potential bug that is blocking me but that probably can cause other problems. I wanted to open a PR myself but I'm not sure of the expected behavior, since that part of the code is undocumented and untested.

I'm referring to this line: https://github.com/tortoise/aerich/blob/dev/aerich/init.py#L57

For my understanding, this creates an entry in the Aerich table with the content of the migration. This should reflect the state of the models after such migration. With the way it is implemented, it only reflects the state of the models in the current version of the code. I can see this when starting from a clean db: all the entries in the Aerich table are the same and contain changes that are in the model files but have nothing to do with the content of the migrations.

I see how it can sometimes work: if somebody runs upgrade with no changes in the code or on an existing db, no problem, because the last version is the one that matters and older migrations' contents are not that relevant for the diff.

This fails for me though: I'm trying to make the generation of the migration files reproducible and scriptable so that a contributor doesn't have to understand aerich but just run a script after changing the models to create a new migration file. This is currently blocked by this behavior/bug of Aerich.

The relevant part of my workflow is as such:

  • change a model file
  • start my script
  • run aerich upgrade on an empty sqlite db
  • run aerich migrate

Here I end up with changes in my Aerich table that reflect the code and therefore the migrate command finds no diff and therefore no version file is generated despite the changes in the model file.

I believe what is in the Aerich table should reflect the result of the upgrade and be aligned with the version files and my use case would be covered. Probably this can impact also other scenarios.

chobeat avatar Oct 09 '22 21:10 chobeat

I have lost more hours than I'm willing to admit debugging migrations because of this, in my opinion generating the migration content from the current app is a less than ideal design choice.

Common developer workflows become annoying because you have to constantly keep this in mind, let's say you're working on some new feature, in the meantime you created about 3 or 4 migrations, things are looking good, now you want to reset to a clean state, delete those new migrations and combine them into 1.

No problem, you think to yourself, just drop your database, run aerich upgrade and then aerich migrate, you might even have a script for this... well now you're met with the dreaded No changes detected, but that makes no intuitive sense, you run a git diff and the changes are right there, you reset your database and local environment over and over thinking that you've messed something up, but the result is always the same.

So to make things right you have to either:

Scenario A: Intact database

  1. Downgrade exactly to the point things were before you made any changes (1 more version down the path and good luck)
  2. Delete the new migration files
  3. Run aerich migrate

Scenario B: Database is gone

  1. Run git stash
  2. Delete the new migration files
  3. Run aerich migrate

Scenario A is annoying because you can't dumbly tear everything down if you like to automate things, your bootstrap/setup script has to be smart enough to take these mechanics under consideration.

Scenario B is especially annoying because it's just so damn easy to fall into it, just have some unstaged changes to your models, checkout some branch where you've got a new migration, run aerich upgrade and enjoy figuring out why your subsequent aerich migrate commands do not work at all.

kita99 avatar Feb 18 '23 20:02 kita99

+1 this seems to have been an issue for a while now and it is extremely painful to handle. The state should be captured based on the DB schema vs the python models.

bmorgan21 avatar Feb 19 '23 16:02 bmorgan21