17

This is the chain of events that has and is happening

  • Day 0: I developed and deployed my app
  • Day 1: I create the new database
  • Day 3: I realized I wanted to add a new row to my existing table. I found flask-migrate and I want to use it to migrate my database.

Currently I am at Day 3

There are plenty of documentations on how to get Flask-migrate running if you start from Day 0. You just call flask db init, flask db migrate and flask db upgrade.

However, for my case, it's a bit different. I ran the commands, and my first version of migration is empty. Then I modified my database schema and generated a new migration. Now my latest migration only has 1 line of migration which is adding the new row to the table.

I realized that none of my migrations have the actual schema to create the database, which is supposed to be the first migration you see if you start flask-migrate on day 1.

If I were to clone my repo from scratch:

flask db migrate will result in alembic.util.exc.CommandError: Target database is not up to date..

flask db upgrade will result in sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) relation "offer" does not exist.

What can I do to fix this?

Tinker
  • 4,165
  • 6
  • 33
  • 72

2 Answers2

38

You have two options.

1) If you only want to track database migrations going forward

  • Run flask db init, to create the migration repository.
  • Add the new column to your database model.
  • Run flask db migrate, to generate a migration. The migration script will only have the new column in it.
  • Run flask db upgrade to apply the new migration to your database.

At this point your database should have the new column, and you can continue working. Repeat the above steps any time you need to make additional changes.

Note that with this approach, you cannot recreate the entire database from scratch. You have to have a way to initialize the database to the schema you had on Day 1, and then you can apply the migration history to that to upgrade it to your current schema.

2) If you want to keep track of the entire migration history, including the schema on the day you are adding Flask-Migrate to your application.

This is a little bit tricky, but it can be done.

  • Start with flask db init, to create the migration repository.
  • Next, you need to trick Flask-Migrate into thinking your database is empty. You can do this by renaming your actual db, and creating a new db with the same name that has no tables in it. In that state, run flask db migrate. This will generate a migration that contains the entire schema of your database.
  • Once you have that initial migration, restore your database to the correct state.
  • Run flask db stamp head to mark the database as updated.
  • Add the new column to your database model.
  • Run flask db migrate again, to generate a second migration. The migration script will only have the new column in it.
  • Run flask db upgrade to apply the new migration to your database.

Hope this helps!

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • 2
    When I run the second `flask db migrate`, I get `alembic.util.exc.CommandError: Target database is not up to date.`. Is there something I need to do (like Django's fake migrations) to get the database up-to-date first? – Giles Thomas Jul 07 '17 at 19:59
  • 3
    You are correct, I missed a step in these instructions. I have corrected the post now with the addition of the `db stamp head` command. – Miguel Grinberg Aug 04 '17 at 15:20
  • Note that this applies well to **flask-migrate** since there will be an existing declarative_base(). – corentingi Mar 01 '18 at 10:16
  • This works great (`flask db stamp head`) for promoting databases changes through dev -> test -> prod too. – naaman May 26 '19 at 03:09
  • I'm super late to this but I already have some users using my flask app, how can I run flask db stamp there for just a single time so there isn't an error that the table already exists? – Thilo Jaeggi Jul 01 '23 at 08:55
0

I used simple step to track of the entire migration history:

  1. Create a new database for temporary use and use this database endpoint.
  2. Removed migration folder if exist.
  3. Run flask db init to create new migration.
  4. Run flask db migrate to initialized your existing module migration from scratch.
  5. Now use the original database endpoint.
  6. Run flask db stamp head this creates alembic_version table in the database with using correct version of migration.

Now good to go use this migration to future used.

Sunil Shakya
  • 8,097
  • 2
  • 17
  • 20