Ignas Butėnas
Ignas Butėnas

Reputation: 6307

Place to initialize DB in Flask

I'm developing app in Flask and it requires DB, so what I have is I do:

app = Flask(__name__)
@app.before_request
def init_db_connection:
  # here I connect to my DB

@app.teardown_request
def destroy_db(exception):
  # here I destroy database connection

On the development server (app.run()) this is not the best place to initialize the database I guess, because also DB will get initialized even it the request comes for the static file. In production I can have a separate web server serving static files, so it shouldn't be a problem.

But still I'm thinking if this is right way to initialize DB or it is better for example to initialize DB in Blueprint which is used in that moment? Just want to know the best practice and how you guys doing this :)

Upvotes: 19

Views: 14311

Answers (2)

ADITYA GUPTA
ADITYA GUPTA

Reputation: 51

Flask Application can be initialised by using inbuilt SQLAlchemy modules.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# create the extension
db = SQLAlchemy()

# create the app
app = Flask(__name__)

# configure the SQLite database
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"

# initialize the app with the extension
db.init_app(app)

Note: The db object gives you access to the db.Model class to define models, and the db.session to execute queries.

Reference: flask_documentation

Upvotes: 1

oxer
oxer

Reputation: 1145

Here are a few options:

  1. Use connection pooling or a library which does connection pooling. This will reduce the overhead so that getting a db connection when you don't need it (e.g., for static files) is not a problem.
  2. In your init_db_connection method, you can check the route and if it is a static route or route where you don't think the db is necessary then don't do the db init.
  3. Use a blueprint and put your init code in the blueprint so routes outside of the blueprint don't do the init.
  4. Create the connection to your database inside a context block in the function which uses it (e.g., see below):
@app.route("/example_using_db")
def example_using_db():
    with MyDBCursor() as cur:  # context manager which connects to db and provides cursor
        data = cur.execute("SELECT * from EXAMPLE").fetchall()
    

Depending on your library, you may be able to get a context manager like above. If not you can either write one or put your code which connects to the db in a try/finally block so that you release the connection if there is an exception.

Upvotes: -2

Related Questions