2

I've read many of the other posts on having models separated from the main app but I can't get it to work with just app.py (my actual app) and models.py (my database models).

If I do the following I get an app.db file with no tables:

from app import db
db.create_all() 

If I do the following I get a RuntimeError: No application found. Either work inside a view function or push an application context.:

from app import db
db.create_all() 

I have also looked at Introduction into Contexts page and can't work out where I put def create_app():, none of it seemed to work in my case.

Here is my app.py:

from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
from models import userTable

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

@app.route('/', methods=['GET', 'POST'])
def home():
    return "home"

if __name__ == '__main__':
    app.run(debug=True)

Here is my models.py:

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

class userTable(db.Model):

    __tablename__ = "userTable"

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)

1 Answer 1

6

Perhaps you could try the following:

app.py

from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
import models
from models import initialize_db

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

initialize_db(app)

@app.route('/', methods=['GET', 'POST'])
def home():
    return "home"

if __name__ == '__main__':
    app.run(debug=True)

models.py

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

def initialize_db(app):
  app.app_context().push()
  db.init_app(app)
  db.create_all()

class userTable(db.Model):

    __tablename__ = "userTable"

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)

The key is creating a database initialization function within models.py which takes the application instance as a parameter. This function only creates the database tables once it has its application instance. This will allow you to import the models module initially without an application instance and still have a modular design.

Sign up to request clarification or add additional context in comments.

6 Comments

Hi Nathan, thank you for this. I've just made the tweaks but I get a "'No application found. Either work inside a view function or push' RuntimeError: No application found. Either work inside a view function or push an application context." :-(
OK worked it out with your help.. in app.py it needs to be with app.app_context(): initialize_db(app) so if you can update your answer and tweak the copy and paste of app.py to include line 1 i.e. from flask import Flask, render_template, request then I will tick accept answer so others can benefit from a full code listing..
Good catch John, sorry I missed a line from the copy and paste. I added the app_context within the database initialization function :). Should be good to go now
OK this may be verging on another question but all the above works except I have no access to the DB, if I try to use db.session.add I get NameError: name 'db' is not defined. It works fine if I had db = SQLAlchemy() in app.py below initialize_db(app). I think for the sake of completion the answer should have that, correct?
So I am assuming you're now trying to add a user in one of your routes? I agree the question is morphing but this is a scoping error and is something that you will have to deal with as your app grows from a simple everything in your app.py, to multiple modules, to potentially becoming a package so it's important for you to understand how scoping works in python. This error is telling you hey I don't have db, which looking at your imports you don't. You currently have the initialize_db() function from your models.py file. So maybe you could also import that db variable from models.py?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.