Ok, i'm a bit new to Flask, so I'm not sure if i should be using Flask Script or Flask's built-in CLI took but I'm going with the latter for now.
However, I'm facing the problem that others have faced when it comes to bootstrapping the app context before running a command and having current_app context and whatnot.
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.cli.add_command(seed_db)
return app
@click.command
@with_appcontext
def seed_db():
# Register SqlAlchemy
from .models import db, User, Role
db.init_app(app)
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
# Some initial models (if they don't exist)
user_datastore.find_or_create_role(name='admin', description='Administrator')
user_datastore.find_or_create_role(name='end-user', description='End user')
return app
So in this case I have a factory method initializing the app. And then I have my custom command that I want to run to seed the database.
I've already been able to run flask db migrate to set up my initial tables, but if I try to run flask seed_db, I get something like this:
File "/usr/local/lib/python3.6/site-packages/click/core.py", line 1150, in add_command name = name or cmd.name AttributeError: 'function' object has no attribute 'name'
Can someone enlighten me on how to properly bootstrap the app with commands outside the create_app method?
There is an error when you are using @click.command
I think the error message gives you a clear clue that you forget to give a name to your command.
You need to init a name to the command like this @click.command("seed_db") or just default function name like this @click.command()
@click.command("seed_db")
@with_appcontext
def seed_db():
# Register SqlAlchemy
from .models import db, User, Role
db.init_app(app)
Hope it helps.
These two lines are in the wrong place:
app.cli.add_command(seed_db)
return app
Your seed_db() function is adding itself to the app, which is a bit confusing - then returning the app. I think you meant for these two actions to occur your app factory method:
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.cli.add_command(seed_db)
return app
Your app factory is the function with the responsibility of setting up the app object and returning it, no other function should be trying to do this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With