Flask implements a set of useful commands that make it easier to handle some development-related tasks elegantly. To list these commands, simply run "flask
" in your CLI:

As we can see, Flask comes with 3 built-in commands, the most common one is "run" which is used to spin up a development server.
In this post, we'll explore how to implement our own command, and add it to the flask utility script.
We are going to create two custom commands, that will be used to create and drop SQL tables from an SQLite database using the SQLAlchemy ORM.
Project setup:
I'll be using the same setup we ended up with in this blog post.
Adding Flask-SQLAlchemy to the project:
We'll be using Flask-SQLAlchemy to interact with our SQLite database.
Installing Flask-SQLAlchemy is as simple as running a pip install:
(venv) $ pip3 install flask-sqlalchemy
Before initializing the Flask-SQLAlchemy extension, we need to add first the configuration values that the extension will load from our app's config.
In app/
create a new Python module called config.py and add the following:
class Config:
SQLALCHEMY_DATABASE_URI = 'sqlite:///app.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_DATABASE_URI: The database URI that should be used for the connection.
SQLALCHEMY_TRACK_MODIFICATIONS: When set to False, tracking is disabled for modification of objects. Tracking requires extra memory, and since we are not tracking anything in this example, we set it to False.
Here's how our project tree looks like so far:
myflaskapp
venv/
app/
__init__.py
config.py
routes.py
.flaskenv
run.py
Let's add now this configuration to our Flask instance and then initialize Flask-SQLAlchemy.
Edit "app/__init__.py
" as follows:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from app.config import Config
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
from app import routes
We imported the SQLAlchemy class from the flask_sqlalchemy extension.
We imported the Config class that we just created.
Right after the flask app initialization, we added the new configuration to the Flask instance using the from_object method.
We created an instance of the SQLAlchemy class and we called it "
db".
Using this SQLAlchemy instance we'll be able to perform pretty much all sorts of interactions with our database.
Adding a Class-based table:
The two commands that we will implement will be responsible to create a SQL table. Let's define a simple User table that has a couple of columns.
In app/
create a new Python module called models.py and add the following:
from app import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
def __repr__(self):
return f'User #{self.id}: {self.username}'
With our current setup, to create the table we just defined we need to open up the Python interactive shell and call the "create_all" method that the SQLAlchemy class implements:
>>> from app import db
>>> from app.models import User
>>> db.create_all()
>>> db.drop_all()
After calling "create_all ", notice the creation of a new file in the app/ directory called "app.db
", this file represents our database where the User table lives.
As you can tell, The problem with this approach is that we would have to go through the same procedure each time we want to drop or create all of our tables.
This is where Flask commands will come in handy.
Writing a Flask command:
Using Click, we'll create two commands:
create-db: A command to create all our tables (models).
clear-db: A command to drop all the tables in the database.
Click is a package for creating CLI tools in Python, Click is also a Flask dependency, so we don't need to manually install it using pip.
We will implement our commands in the run.py
module since it's the entry point of our app, but you can always create a new module and store the commands there.
A Click command is just a Python function decorated with a decorator provided by the Click package, and named "command
". So creating a command with Click is as easy as defining a Python function, and letting the "command
" decorator do the heavy lifting.
In run.py
, let's write two commands and keep them empty for now:
import click
from app import app, db
@click.command(name='create-db')
def create_db():
"""Create database tables"""
pass
app.cli.add_command(create_db)
@click.command(name='clear-db')
def clear_db():
"""Drop database tables"""
pass
app.cli.add_command(clear_db)
if __name__ == '__main__':
app.run(debug=True)
We imported the click package, to get access to the command decorator.
We imported the SQLAlchemy instance "db".
We created two functions:
create_db, clear_db.
We applied the "
command
" for the two functions to make them Click commands.The command decorator by default uses the function name as the name of the command. We can set a custom name to our command by passing the parameter "
name"
to the decorator.To add a command to the Flask CLI, we register the command using the
"add_command" method
that "cli" module within Flask implements.
Let's list the Flask commands again to see if our new commands were taken into account:
In your CLI run the flask command:

As we can see, the commands we just implemented are now available with the Flask CLI.
Notice how each function's docstring was used as a description of the command, so always make sure to write meaningful docstrings for your commands.
All that is left now is to implement the logic of each command, so let's update the run.py module:
import click
from app import app, db
@click.command(name='create-db')
def create_db():
"""Create database tables"""
from app.models import User
db.create_all()
click.echo('Created database tables.')
app.cli.add_command(create_db)
@click.command(name='clear-db')
def clear_db():
"""Drop database tables"""
from app.models import User
db.drop_all()
click.echo('Cleared database')
app.cli.add_command(clear_db)
if __name__ == '__main__':
app.run(debug=True)
We imported the User model for each command.
We call the "
create_all
" method on the SQLAlchemy instance "db
", to create all the defined models.We call the "drop_all" method on the SQLAlchemy instance "
db
", to drop all the defined models.The
"echo"
function is a utility function provided by the Click package, to print to stdout, you can think of it as an improved version of the built-in print function.
Executing the commands:
Since our commands are now registered in the Flask CLI, we can execute them directly just like the other flask built-in commands.
create-db command:
In you CLI execute the command "flask create-db":

After executing the command, the message we passed to the echo function was printed in the CLI.
To check if the table was created, I'll use the sqlite3
command to inspect the database:

Looks our table was created successfully. Our command is producing the results we expected.
clear_db command:
In you CLI execute the command "flask clear-db":

Let's take a look at our database and see if the User table was deleted:

Looks like our database doesn't have any table...
The create_db command works as expected.
Note:
The example we just went through is very a simple use-case of Flask commands, you can write commands that execute complex tasks; for example, a command that will be executed as a Cron job once every month to reset some kind of counter for every user in a database.