mas
mas

Reputation: 1245

db.create_all not creating tables in pytest-flask

I'm self documenting a solution to db.create_all for anyone that has this problem. Hopefully it will help someone.

Here is a list of other threads that did not help me:

I tried creating and destroying a db in a conftest.py for pytest. Alembic autogenerate was working for me but for some reason db.create_all was not. Importing the models before the db.create_all did nothing. Neither did importing the models just after db = SQLAlchemy() in my __init__.py (I was using the application factory pattern). I was also using a Declarative Base, which may be part of the problem.

Every run of pytest resulted in the following error:

ERROR tests/test_main.py::test_index - sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "rule" does not exist

Upvotes: 1

Views: 1684

Answers (1)

mas
mas

Reputation: 1245

The solution was to short-circuit Flask-SQLAlchemy's method of hanging create_all on the db object.

I followed the pattern in the actual SQLA docs:

Base.metadata.create_all(engine)

So in my conftest setup and destruction instead of db.create_all() and db.drop_all():

@pytest.fixture
def app():
    app = create_app(TestConfig)

    with app.app_context():
        from app.models import Access, Rule, Base
        Base.metadata.drop_all(db.engine)
        Base.metadata.create_all(db.engine)
        print("Creating all")
        main(app)

    yield app

    with app.app_context():
        db.session.remove()
        Base.metadata.drop_all(db.engine)
        print("Dropping all")

This solved the problem. Tests now pass, tables created and destroyed.

Upvotes: 2

Related Questions