No application found on Flask function - python

I have two file one for the DB model and the other is the main file. The creat_admin_user function does not work. When I try to run init.py I get "No application found. Either work inside a view function or push an application context". I have looked at the SQLAlchemy site and I have the db.init_app line and returning the app object. Not sure what else I am missing. The error appears to be on the user query which is the first line of the create_admin_user function.
--------------- __init__.py ---------------
from .models import User, Note, db, DB_NAME
from flask import Flask
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
create_database(app)
# create Admin user
create_admin_user()
return app
def create_database(app):
if not path.exists('website/' + DB_NAME):
db.create_all(app=app)
print('Created Database!')
def create_admin_user():
user = User.query.filter_by(username='admin').first()
print("after query")
if user:
print("User already exists")
else:
# Add user to DB
add_user = User(first_name='LocalAdmin', username='admin', password=generate_password_hash(gen_password,
method='sha256'))
# adds user and commits the db.session.add(add_user)
db.session.commit()
print(f"Admin user created successfully")
--------------- Models.py ---------------
import datetime
from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.sql import func
db = SQLAlchemy()
DB_NAME = "database.db"
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(100))
last_name = db.Column(db.String(100))
email = db.Column(db.String(100))
username = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(100))
domain = db.Column(db.String(100), nullable=False)
creation_date = db.Column(db.DateTime, default=datetime.datetime.now())
last_login = db.Column(db.DateTime, onupdate=datetime.datetime.now())
failed_login = db.Column(db.Integer)
active = db.Column(db.Integer, default=1)

Got it working. I added app.app_context().push() right before calling the create_admin function and it is working correctly now.

If you want to run functions which alters the Database of an Flask Application without starting the Flask Application you have to push the Application Context first.
So you have to call something like this:
self.app = create_app()
self.app_context = self.app.app_context()
self.app_context.push()
And don't forget to remove the context afterwords.
self.app_context.pop()

Related

OperationalError no such table: use when adding new users to SQLite database [fixed]

I'm making a website using Flask and using flasksqlalchemy for making new users, but when I commit to add the new user to the database, I get a sqlalchemy.exc.OperationalError.
Here is the code for my models.py file:
from .__init__ import db
from flask_login import UserMixin
from sqlalchemy.sql import func
class Reservation(db.Model):
id = db.Column(db.Integer , primary_key=True)
data = db.Column(db.String(128))
date = db.Column(db.DateTime(timezone=True), default=func.now())
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
class user(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
userName = db.Column(db.String(128))
password = db.Column(db.String(128), unique=True)
reservations = db.relationship("Reservation")
Here's the code for my init.py file:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{DB_NAME}"
print("Initializing app")
db.init_app(app)
print("App initialized")
print("Importing blueprints...")
from .views import views
from .auth import auth
app.register_blueprint(views, url_prefix="/")
app.register_blueprint(auth, url_prefix="/")
print("Registered Blueprints")
print("Importing database")
from .models import user, Reservation
print("Creating database")
create_database(app)
db.create_all(app=app)
return(app)
def create_database(app):
print("Checking if DB exists")
if not path.exists("website/" + DB_NAME):
db.create_all(app=app)
print("DB did not exist, has been created right now.")
else:
print("DB exists, nothing has been done.")
And here is the code giving me an error:
print("Adding user to database")
new_user = user(userName=username, password=gph(password,method="sha256"))
db.session.add(new_user)
db.session.commit()
Here is the error log:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user
[SQL: INSERT INTO user ("userName", password) VALUES (?, ?)]
[parameters: ('bingusCoder', 'sha256$vYx5OSQyP182M8Jw$85e0690712b68b4b11e181904b44387eba2c1e1cdacebfbb4a60426c4ecdee81')]
(Background on this error at: https://sqlalche.me/e/14/e3q8)
More info on errors
Edit: fixed it by putting all code into 1 file
I try to reproduce the problem with your code, but it works in my side. In this case, I will just send my working copy of your code so that you can reference from it.
from os import path
from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.sql import func
from flask import Flask
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{DB_NAME}"
print("Initializing app")
db.init_app(app)
return app
def create_database(app):
print("Checking if DB exists")
if not path.exists(DB_NAME):
db.create_all(app=app)
print("DB did not exist, has been created right now.")
else:
print("DB exists, nothing has been done.")
class Reservation(db.Model):
id = db.Column(db.Integer , primary_key=True)
data = db.Column(db.String(128))
date = db.Column(db.DateTime(timezone=True), default=func.now())
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
class user(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
userName = db.Column(db.String(128))
password = db.Column(db.String(128), unique=True)
reservations = db.relationship("Reservation")
app = create_app()
create_database(app)
db.create_all(app=app)
#app.route("/")
def hello_world():
username, password = "username21", "password"
new_user = user(userName=username, password=password)
db.session.add(new_user)
db.session.commit()
return "<p>Hello, World!</p>"

Flask migration is not applying on all tables

i have a project where i create four tables (users,products, agents, customer) when i do migration with:
flask db init,
flask db migrate,
flask db upgrade,
only users and products get migrated
here it is the structure of my project:
my code for user model is:
from main.extensions import db
from main.shared.base_model import BaseModel, HasCreatedAt,
HasUpdatedAt
class User(BaseModel, HasCreatedAt, HasUpdatedAt):
tablename = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String, unique=True, nullable=False)
password = db.Column(db.String, nullable=False)
phone = db.Column(db.Integer)
my code for every module starting by agent model:
from main.extensions import db
class Agent(db.Model):
__tablename__ = 'agents'
id = db.Column(db.Integer, primary_key=True)
picture = db.Column(db.String)
def __init__(self,email, password, phone, picture):
self.email = email
self.password=password
self.phone=phone
self.picture=picture
and for the model in customer is:
from main.modules.user.models import User
from main.extensions import db
class Customer(User):
__tablename__ = 'customers'
approved = db.Column(db.Boolean)
picture = db.Column(db.String)
def __init__(self, email, password, phone, picture, approved):
self.approved = approved
self.picture = picture
User.__init__(self,email,password,phone)
and finnaly the products model has:
from main.extensions import db
from main.shared.base_model import BaseModel, HasCreatedAt, HasUpdatedAt
class Product(BaseModel, HasCreatedAt, HasUpdatedAt):
__tablename__ = 'products'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
the settings.py contains the following code:
and this init files for every model contains this code:
for the user __init.py:
from main.modules.users.api import blueprint as api
for the customer __init.py:
from main.modules.customer.api import blueprint as api
for the agent__init.py:
from main.modules.agent.api import blueprint as api
for the prodcut__init.py:
from main.modules.product.api import blueprint as api
import os
class DevSettings(Settings):
DEBUG = True
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI="sqlite:///" + os.path.join(basedir, "data.sqlite")
SQLALCHEMY_TRACK_MODIFICATIONS=False
and the extension.py contains:
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
migrate = Migrate()
and the app.py contains this:
from flask import Flask, Blueprint
from main.extensions import db, migrate
from main.modules import product, agent, customer, user
from main.settings import DevSettings
MODULES = [ agent, customer,product, user]
main = Blueprint('main', __name__)
def create_app(settings=DevSettings):
app = Flask(__name__)
# Utiliser la configuration (settings).
app.config.from_object(settings)
app.config['SECRET_KEY'] = 'mysecretkey'
# On initialise les libraries Python.
# Init SQLAlchemy.
db.init_app(app)
# Init Migrate.
migrate.init_app(app, db)
app.register_blueprint(main)
register_modules(app)
return app
def register_modules(app):
for m in MODULES:
if hasattr(m, 'api'):
app.register_blueprint(m.api)

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))
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.
Flask needs to be told how to import it, by setting the
FLASK_APP:(venv) $ export FLASK_APP=microblog.py
If you are using Microsoft Windows, use set instead of export in the command above.

SQLAlchemy don't create tables if using Marshmallow

I'm trying to create a project using Flask, Flask-SQLAlchemy, flask-restplus and marshmallow (tried with flask-marshmallow too), but the integration of these tools does not work very well.
Everytime I include some new lib, a new error occur.
I already give up to use migrations with Flask-SQLAlchemy because for some reason, this thing don't work. But now, the problem is with marshmallow.
I'm trying to make with modules and I think this is the part of the problem (all examples of Flask-SQLAlchmey, flask-restplus, flask-marshmallow, etc put everything in a single file)
This is my app.py:
from flask import Flask, Blueprint
import settings
from api import api
from database import init_database, reset_database
app = Flask(__name__)
def configure_app(flask_app):
flask_app.config['SERVER_NAME'] = settings.SERVER_ADDRESS
flask_app.secret_key = settings.SECRET_KEY
def initialize_app(flask_app):
configure_app(flask_app)
blueprint = Blueprint('api', __name__, url_prefix=settings.URL_PREFIX)
api.init_app(blueprint)
# api.add_namespace(auth_login_namespace)
flask_app.register_blueprint(blueprint)
init_database(flask_app)
if settings.DEBUG:
reset_database(flask_app)
def main():
initialize_app(app)
app.run(debug=settings.DEBUG)
if __name__ == '__main__':
main()
api/__init__.py:
import settings
from flask_restplus import Api
api = Api(
version='1.0',
title='Test',
description='Some description'
)
#api.errorhandler
def default_error_handler(e):
message = 'An unhandled exception occurred.'
if not settings.DEBUG:
return {'message': message}, 500
database/__init__.py:
from flask_sqlalchemy import SQLAlchemy
import settings
db = SQLAlchemy()
def init_database(flask_app):
flask_app.config['SQLALCHEMY_DATABASE_URI'] = settings.DATABASE_URI
flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
global db # I really don't like this! :(
db = SQLAlchemy(flask_app)
def reset_database(flask_app):
from database.models import User
db.drop_all()
db.create_all()
db.session.add(User(username='admin', email='abc#def.com', name='admin', password='123', admin=True)
db.session.commit()
I have my app, with only one model until now:
database/models/User.py:
from marshmallow import Schema, fields
from sqlalchemy import func
from database import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, index=True)
email = db.Column(db.String(120), unique=True, index=True)
name = db.Column(db.String(200), nullable=False)
password = db.Column(db.String(200), nullable=False)
admin = db.Column(db.Boolean, nullable=False, default=False)
created_on = db.Column(db.DateTime, nullable=False, server_default=func.now())
class UserSchema(Schema):
id = fields.Int(dump_only=True)
username = fields.Str()
email = fields.Email()
name = fields.Str()
password = fields.Str()
admin = fields.Bool()
created_on = fields.DateTime()
now, if I use the following code (this code is called everytime my app start on debug mode, on function reset_database, in file database/__init__.py):
db.drop_all()
db.create_all()
db.session.add(User(username='admin', email='abc#def.com', name='admin', password='123', admin=True)
db.session.commit()
the User table is not created, and the admin is not inserted on table, because the table don't exist (db.create_all() don't create anything).
sqlite3.OperationalError: no such table: user.
For some reason, if I remove the class UserSchema (on database/models/User.py), the db.create_all() function create the table).
Got working right now:
on database/__init__.py, altered the init_database function to:
def init_database(flask_app):
flask_app.config['SQLALCHEMY_DATABASE_URI'] = settings.DATABASE_URI
flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(flask_app)
and in database/reset_database.py:
def reset_database(flask_app):
with flask_app.app_context():
from database.models.user_module import User
db.drop_all()
db.create_all()
db.session.add(User(username='admin', email='abc#def.com', name='admin', password='123', admin=True))
db.session.commit()
The problems was the init_app, use the app_context, and I'm importing the wrong User module (tks Fian)

python flask sqlalchemy, i can'trun my db_create.py

Ame getting this error of TypeError: init() takes exactly 1 argument (5 given)...where have i gone wrong?? any help i will appreciate ,thanks
thats my db_create.py file
from app import db
from models import post
db.create_all()
db.session.add(post("Good", "i\m good","yes","hae"))
db.session.add(post("Good", "hahaha"))
db.session.add(post("Good", "you"))
db.session.add(post("Good", "hahaha"))
my model.py file is
from app import db
class post(db.Model):
# table name
__tablename__ = "signup"
#columns names
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
email= db.Column(db.String, nullable=False)
password = db.Column(db.String, nullable=False)
confirm= db.Column(db.String, nullable=False)
def __init__(self, username, email, password, confirm):
self.username = username
self.email = email
self.pasword = password
self.confirm = confirm
def __repr__(self,*args, **kwargs):
return '<username {}'.format(self.username), 'email{}'.format(self.email),'password{}'.format(self.password)
this is my init
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.secret_key = "my previous"
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///signup.db'
db = SQLAlchemy(app)
from app import views
You don't need the __init__ method in your post model. Just use the __init__ method inherited from db.Model and you should be fine.
But then I believe you'd need to modify your db_create.py a bit:
For example:
db.session.add(post(username="User", email="user#email.com", password="password", confirm="Yes"))
Also you need to remember to commit your changes:
db.session.commit()

Categories