3

I have a fairly large Flask app, and my typical workflow to create new data tables is as follows:

I create a class in models.py, such as the below:

class ExampleModel(db.Model):
    __tablename__ = 'example_table'

    id = db.Column(db.Integer, primary_key=True)
    text = db.Column(db.String(100))

Then I run flask db migrate and flask db upgrade. After these commands, the table is created and I can insert data normally

item = ExampleModel(text='something')
db.session.add(item)
db.session.commit()

Up until now I've had no problems using the above workflow, even immediately before I started having issues. I added a table, and then added some columns to it, and basically just ran into trouble with the nullable values and whatnot (user error). I didn't do much other than delete some model classes, migration scripts, and manually deleted a table in psql (I am using Postgres).

Now, I am unable to execute a test case (ExampleModel) from above. When I try this simple example, no migration script is created in the migrations directory

Output from flask db migrate:

INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.

Output from flask db upgrade:

INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.

Things I've tried:

  • Rebasing from master, essentially starting over
  • Using the test model above
  • Deleting migrations directory and creating a new one

My config and init files should be fine- they are unchanged since this was last working. I'm stumped on this one

Dr. Funkenstein
  • 416
  • 4
  • 14
  • It might be worth reviewing https://alembic.sqlalchemy.org/en/latest/autogenerate.html#what-does-autogenerate-detect-and-what-does-it-not-detect – Dave W. Smith Sep 12 '21 at 18:28
  • There was an old bug in Flask-Migrate's configuration for Alembic that caused some error messages to not be printed to the terminal. I believe this was fixed some time ago, so my suggestion is that you check if you are using the latest Flask-Migrate, because those migrate and upgrade commands showing no useful output are definitely not normal. If you see this with the latest Flask-Migrate, then I can look into the logging configuration some more to see if any issues remain. – Miguel Grinberg Sep 13 '21 at 14:01

2 Answers2

5

After a bit I was able to get it working. This is what I did:

  • Deleted alembic_version table from my db (DROP)
  • Made a new alembic_version table with flask db stamp head

From there I was able to add tables using the typical workflow.

I'm leaving this open because I'm not sure that the above is actually the correct approach to solve- I may have done something else while I was working on it

Dr. Funkenstein
  • 416
  • 4
  • 14
1

Had this problem similarly to OP & their answer. Their answer worked for me, but adding some more details:

  • I had deleted a migration file after a successful db upgrade without downgrading first.
  • As a result, my alembic_version was out of sync. The alembic_version table was referencing a version that did not exist.
  • When I tried to run a db upgrade/downgrade/migrate script, nothing worked. Output was:
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.

By deleting the alembic_version table and recreating it with flask db stamp head, it brought me back in sync with my last db migration (if I knew my last head, I probably could have just deleted the value). I then ran flask db migrate -m "comment" and it worked perfectly.

Additional helpful scripts as per the Flask-Migrate docs that may have avoided the need to drop the table:

flask db stamp [--sql] [--tag TAG] <revision>
    Sets the revision in the database to the one given as an argument, without performing any migrations.

flask db current [--verbose]
    Shows the current revision of the database.

flask db history [--rev-range REV_RANGE] [--verbose]
    Shows the list of migrations. If a range isn’t given then the entire history is shown.

flask db show <revision>
    Show the revision denoted by the given symbol.

So: check the flask db current against the list of flask db history, and reset with flask db stamp [--sql] [--tag TAG] <revision>.

Adding as a separate answer b/c don't have enough points to add the "why this worked" as a comment.

sharedphysics
  • 25
  • 1
  • 10