Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask Shell Commands not working

I'm new to python and flask and currently working on the Flask Mega-Tutorial, however: I'm stuck getting flask shell to recognize my custom symbols/commands.

When I try to access the model User as a symbol by typing flask shell in my virtual environment, I get NameError: name 'User' is not defined.

User should return: <class 'application.models.User'>, but shows the error instead.

What I don't understand is that the app symbol seems to work fine and returns <Flask 'application'> as it should.

What am I doing wrong here? Something with the imports?

I did some research: this looks like my problem but does not use the app.sell_context_processor decorator.

I tried also variations of my code: both changing import names from app to application as I changed these from the default in the tutorial and using user instead of User (lower vs. uppercase), but nothing seems to work.

Please help me fix this!

Error

    (venv) MBP:books mbpp$ flask shell
    Python 3.6.5 (default, Mar 30 2018, 06:42:10) 
    [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
    App: application
    Instance: /Users/mbpp/Sites/books/instance
    >>> app
    <Flask 'application'>
    >>> User
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
    NameError: name 'User' is not defined

My code from application.py

   from application import app, db
   from application.models import User, Book, State, Course, BookTitle, Author

   @app.shell_context_processor
   def make_shell_context():
       return {'db': db, 'User': User, 'State': State, 'BookTitle': BookTitle, 'Author': Author}

and from __init__.py

    from flask import Flask
    from config import Config
    from flask_sqlalchemy import SQLAlchemy
    from flask_migrate import Migrate
    from flask_login import LoginManager

    # initiate the Flask app
    app = Flask(__name__)

    # use the config.py file for configuration
    app.config.from_object(Config)

    # use SQLAlchemy for database management
    db = SQLAlchemy(app)

    # use Flask-Migrate extension for database migration management
    migrate = Migrate(app, db)

    # use Flask-Login extension for login form
    login = LoginManager(app)
    login.login_view = 'login'

    from application import routes, models

and from models.py (I'm building a website where users can sell books)

   from application import db, login
   from datetime import datetime
   from werkzeug.security import generate_password_hash, 
   check_password_hash
   from flask_login import UserMixin

   # create a table to store users
   class User(UserMixin, db.Model):
        id = db.Column(db.Integer, primary_key = True)
        username = db.Column(db.String(64), index = True, unique = True)
        email = db.Column(db.String(120), index = True, unique = True)
        password_hash = db.Column(db.String(128))
        phone = db.Column(db.String(64))
        books = db.relationship('Book', backref='seller_name', lazy='dynamic')

    def __repr__(self):
        return '<User: {}>'.format(self.username)

    # create a password hash
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    # check the password hash against a user given password
    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

    # create a table to store information on a book for sale
        class Book(db.Model):
            id = db.Column(db.Integer, primary_key = True)
            course_id = db.Column(db.Integer, db.ForeignKey('course.id'))
            title = db.Column(db.Integer, db.ForeignKey('booktitle.id'))
            author = db.Column(db.Integer, db.ForeignKey('author.id'))
            price = db.Column(db.Integer)
            isbn = db.Column(db.String(64), index = True)
            state_id = db.Column(db.Integer, db.ForeignKey('state.id'))
            state_description = db.Column(db.String(256))
            seller_id = db.Column(db.Integer, db.ForeignKey('user.id'))
            creation_timestamp = db.Column(db.DateTime, index = True, default = datetime.utcnow)

        def __repr__(self):
            return '<Book: {}>'.format(self.title)

    # create a table to store different states books can be in
        class State(db.Model):
            id = db.Column(db.Integer, primary_key = True)
            name = db.Column(db.String(128), index = True)
            books = db.relationship('Book', backref='state', lazy='dynamic')

        def __repr__(self):
            return '<State: {}>'.format(self.name)

    # create a table to store courses
        class Course(db.Model):
            id = db.Column(db.Integer, primary_key = True)
            name = db.Column(db.String(128), index = True)
            year = db.Column(db.Integer, index = True)
            books = db.relationship('Book', backref='course', lazy='dynamic')

        def __repr__(self):
        return '<Course: {}>'.format(self.name)

    # create a table to store booktitles
        class BookTitle(db.Model):
            id = db.Column(db.Integer, primary_key = True)
            title = db.Column(db.String(128), index = True)
            books = db.relationship('Book', backref='book_title', lazy='dynamic')

        def __repr__(self):
           return '<Book title: {}>'.format(self.title)

    # create a table to store authors
        class Author(db.Model):
        id = db.Column(db.Integer, primary_key = True)
        name = db.Column(db.String(128), index = True)
        books = db.relationship('Book', backref='author_name', lazy='dynamic')

        def __repr__(self):
            return '<Author: {}>'.format(self.name)

     # user loader for Flask-Login extension, gets users ID
     @login.user_loader
     def load_user(id):
         return User.query.get(int(id))
like image 217
StackTT Avatar asked Apr 03 '18 09:04

StackTT


People also ask

How do I run a flask in command prompt?

Click the + (Add New Configuration) button and select Python. Give the configuration a name such as “flask run”. For the flask run command, check “Single instance only” since you can't run the server more than once at the same time. Select Module name from the dropdown (A) then input flask .

What is Shell_context_processor?

shell_context_processor decorator registers the function as a shell context function.


1 Answers

Thanks a lot to Miguel, the writer of the FLASK Mega Tutorial (go check that out) wo solved my problem!

As he pointed out in a comment below my question: you cannot have a module and a package with the same name. So no application folder and application.py at the same time.

Solution:

I changed my 'application.py into 'theapp.py' and now flask shell works like a charm! I did not need to change anything in my files, apart from running export FLASK_APP=theapp.py in the terminal.

like image 174
StackTT Avatar answered Oct 05 '22 14:10

StackTT