Issue
To summarize my problem, I try to generate my PostgreSQL database tables with the SQLAlchemy command db.create_all() and it returns the following error:
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
I have of course followed the documentation and threads on this platform and tried different alternatives:
from app import db, create_app
db.create_all()
This approach still fails with the same message. Another alternative was to include the create_app function inside the create_all() function so that it would have the correct context.
db.create_all(app=create_app())
This generated a new error because when the create_app() function is executed, it needs environment variables (I don't know how to include the variables through the python terminal).
db.init_app(app)
with app.app_context():
db.create_all()
migrate.init_app(app, db)
mail.init_app(app)
The result of this execution is NOTHING. Absolutely nothing happens inside the database, I am 100% sure that there is connectivity between my run and my database but no table or any kind of error is generated.
Of all the alternatives I think the most reasonable is to run the creation through the python terminal, however, I have the problem of environment variables that I already include by powershell when I run my application but it does not help me to initialize the database from the terminal.
Could someone give me some hint or help in some direction?
Solution
Greetings to everyone who has been interested in this thread and special thanks to mechanical_meat for his support and assistance.
I have learned a lot about python applications and the reasons why my application was failing. First of all I think that to understand the solution it is necessary that I comment my project structure:
├── entrypoint.py
├── config
├── app
│ ├── __init__.py
│ │ └── models.py
│ ├── module 1
│ │ └── models.py
│ ├── module 2
│ ├── module N
│ │ └── models.py
In case I needed to launch my application, I activated my virtual environment and added the necessary environment variables (FLASK_ENV, FLASK_APP or APP_SETTINGS_MODULE).
At this point if I try to run db.create_all() I get the error from this thread that the application context does not exist as only the following lines exist within my entrypoint:
from flask import send_from_directory
import os
from app import create_app
settings_module = os.getenv('APP_SETTINGS_MODULE')
app = create_app(settings_module)
if __name__ == '__main__':
app.run(debug=True)
My solution in this case has been a silly one. The only thing I have done is to create two python files at the same height as my entrypoint. The first one contains information similar to my app generator but with the difference that all the variables in it are initialised with the configurations (from a security point of view it's a bad approach):
from flask import Flask
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SECRET_KEY'] = 'SECRET'
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:...'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
login_manager = LoginManager(app)
login_manager.login_view = "login"
db = SQLAlchemy(app)
from models_db import User, Task, History
The other file includes the declaration of the classes to load the columns correctly. And, with this solution the generation of the database tables has worked, the only additional change has been to change the environment variable from app to my new class that is in charge of creating the DB. This is necessary because my goal is that it can be included in a dockerfile and the tables are created automatically.
I reiterate my thanks to all of you who have bothered to read this thread, if anyone has a more elegant solution I will be happy to analyse it in depth. If this can help someone else to reach a solution that would be great.
Answered By - Buscatrufas Answer Checked By - Terry (WPSolving Volunteer)