3
votes

I have a Docker setup, with a Flask app and a Postgresql backend. I want to be able to create all of my tables in Postgres from their Models defined in Flask-SqlAlchemy. This is currently not working for me.

In my app __init__.py I create my app with config files.

from flask import Flask


def create_app():
    app = Flask(__name__)
    app.config.from_pyfile("config.py")
    app.config.from_pyfile("secrets.py")
    return app


app = create_app()


from app import routes

In my routes.py I make the DB from the app, and then set it up before the first request(with my Models imported):

from .models import User, Community, Post, Debate

...

db = SQLAlchemy(app)


@app.before_first_request
def setup():
    db.init_app(app)
    with app.app_context():
        db.metadata.drop_all(bind=db.engine)
        db.metadata.create_all(bind=db.engine)
        db.session.commit()

My models inherit from a BaseModel I made which inherits from db.Model, where db is an import of the db I defined in routes.py.

What am I doing wrong here? How can I make flask-sqlalchemy automatically create my tables for me? Am I barking up the wrong tree?

1

1 Answers

2
votes

I would suggest not doing your db setup and teardown before the first request. It will actually wait for the first request, and before serving it, fire the before_first_request handler. This will cause the first request to your service to hang.

Instead consider handling db setup within your create_app factory.

from flask import Flask
from models import db  # Or wherever you have it

def create_app():
    app = Flask(__name__)
    app.config.from_pyfile("config.py")
    app.config.from_pyfile("secrets.py")

    # Database setup
    db.init_app(app)
    db.drop_all()  # This will delete everything
    db.create_all()  # This creates on the table schema
    return app


app = create_app()


from app import routes