2

I use a simple stack of Python (3.6.4), Flask (0.12.2), flask_admin (1.5.1) and flask_sqlalchemy (2.3.2). I chose SQLite as my DB.

The structure of my project is rather simple:

1) shared_db.py

from flask_sqlalchemy import SQLAlchemy 
db = SQLAlchemy()

2) models.py

from shared_db import db

class City(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)

def fill_data(app):
    with app.app_context():
        db.create_all()
        db.session.add(City(name="Moscow"))
        db.session.add(City(name="New York"))
        db.session.add(City(name="London"))
        db.session.add(City(name="Paris"))
        db.session.commit()

3) model_views.py

from flask_admin.contrib.sqla import ModelView

from models import City

class CityView(ModelView):
    column_display_pk = True    # to force ids to appear in the Admin panel
    column_hide_backrefs = False
    column_list = ("id", "name")


def create_views(admin, db):
    admin.add_view(CityView(City, db.session))

4) app.py

import os

from flask_admin import Admin
from flask import Flask, jsonify, make_response, request

from shared_db import db
from models import fill_data
from model_views import create_views

app = Flask(__name__)
app.config["SECRET_KEY"] = "123456790"
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////<path to the project>/myDB'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

db.init_app(app)
fill_data(app)

admin = Admin(app, 'My app')
create_views(admin, db)

if __name__ == "__main__":
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port, debug=True)

Finally, I delete the myDB-file if it exists and I run the app with python3 app.py.

Surprisingly, eventually, I got 8 cities instead of 4! I perform some debug with DB Browser and find out that duplicated 4 cities creates right after the very last line of code - app.run(...) - executes.

How do I run the flask app correctly with a pre-filled database?

1 Answers1

2

If you need to seed the database every time the app begins, you will want to make the act of populating the database idempotent. In other words, you need to check if the object already exists before you create it (because it is completely possibly for the app to restart when you have not deleted the database). This post might help you accomplish this behavior with SQLAlchemy.

MrName
  • 2,363
  • 17
  • 31