I have created a flask app with Flask-Sql-Alchemy, however flask in't recognising the database table User_Plans I created and trying to query.
It gives the following error:
NameError: name 'User_Plans' is not defined.
I could be wrong, but it feels like the error is a scoping issue.
I have included my code below.
Can you help? Many thanks in advance.
database.py
from flask_sqlalchemy import SQLAlchemy
from flask_user import UserManager, UserMixin, SQLAlchemyAdapter
from datetime import datetime
def create_db(app):
db = SQLAlchemy(app)
class User(db.Model, UserMixin):
id=db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(50),nullable=False,unique=True)
password = db.Column(db.String(255),nullable=False, server_default='')
active=db.Column(db.Boolean(),nullable=False,server_default='0')
email = db.Column(db.String(255),nullable=False,unique=True)
confirmed_at = db.Column(db.DateTime())
plan_id=db.Column(db.Integer, db.ForeignKey('plans.id'),default=1)
db_adapter = SQLAlchemyAdapter(db,User)
user_manager = UserManager(db_adapter,app)
class User_Plans(db.Model):
id=db.Column(db.Integer,primary_key=True)
user_id=db.Column(db.Integer, db.ForeignKey('user.id'))
plan_id=db.Column(db.Integer, db.ForeignKey('plans.id'))
start_date = db.Column(db.DateTime())
class User_APIs(db.Model):
id=db.Column(db.Integer,primary_key=True)
user_id=db.Column(db.Integer, db.ForeignKey('user.id'))
api_id=db.Column(db.Integer, db.ForeignKey('tools.id'))
api_key=db.Column(db.String(50),nullable=False,unique=True)
class Tools(db.Model):
id=db.Column(db.Integer,primary_key=True)
tool=db.Column(db.String(50),nullable=False,unique=True)
class Plans(db.Model):
id=db.Column(db.Integer,primary_key=True)
plan=db.Column(db.String(50),nullable=False,unique=True)
price=db.Column(db.Float(5),nullable=False)
credit=db.Column(db.Integer,nullable=False)
class Usage(db.Model):
id=db.Column(db.Integer,primary_key=True)
user_id=db.Column(db.Integer, db.ForeignKey('user.id'))
task_id=db.Column(db.Integer, db.ForeignKey('tasks.id'))
datetime=db.Column(db.DateTime())
class Tasks(db.Model):
id=db.Column(db.Integer,primary_key=True)
task=db.Column(db.String(50),nullable=False,unique=True)
credit=db.Column(db.Integer,nullable=False)
class Status(db.Model):
id=db.Column(db.Integer,primary_key=True)
status=db.Column(db.String(20),nullable=False,unique=True)
__init__.py
from flask import Flask
from flask import render_template
from flask_mail import Mail
from config import config
from database import create_db
from flask_user import login_required, current_user
from dateutil.relativedelta import relativedelta
from datetime import datetime
def create_app(config_name):
print(config_name)
app = Flask(__name__)
app.config.from_object(config[config_name])
create_db(app)
mail = Mail(app)
#app.route('/')
#login_required
def index():
user_id = current_user.id
start_date=User_Plans.query.with_entities(User_Plans.start_date).filter(User_Plans.user_id==user_id).first()
return '<h1>Hello {}, you started your plan on {}</h1>'.format(current_user.username,start_date.strftime('%d-%m-%Y'))
manage.py
from app import create_app
app = create_app('development')
if __name__== '__main__':
app.run()
It isn't talking about your table, it's talking about the name User_Plans, which is indeed not defined in your main code. You need to import it - and any other models you use - into that file.
from models import User_Plans
Related
I followed some tutorial of flask factory pattern and tried to refactor my project. The database I use is a MySql container. Everything works fine before refactoring.
Now I came into an error sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user and I guess the problem is due to isolated db instance because I never use sqllite in my project. But I fail to debug it. I also use blutprint to orgnize the strcture.
Here is the code relating to the error:
baseClasses.py
from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
db = SQLAlchemy()
login_manager = LoginManager()
login_manager.login_view = "login"
login_manager.login_message_category = 'info'
bcrypt = Bcrypt()
#login_manager.user_loader
def load_user(user_id):
return User.query.get(user_id)
class User(db.Model, UserMixin):
__tablename__ = "user"
usr = db.Column(db.String(50),primary_key=True,unique=True,nullable=False)
psd = db.Column(db.String(100), nullable=False)
role = db.Column(db.String(50), default="viewer")
def __repr__(self):
return f"User('{self.usr}','{self.psd}','{self.role}')"
def get_id(self):
return (self.usr)
class DataModel(db.Model):
__abstract__ = True
own_id = db.Column(db.Integer, primary_key = True, autoincrement = True, nullable = False)
name = db.Column(db.String(255), nullable = False)
project = db.Column(db.String(100), nullable = False)
last_user = db.Column(db.String(50))
path = db.Column(db.String(255), nullable = False)
model.py, the class TO is one example of all other classes, each of them has a table in the database.
from storage_flask.baseClasses import DataModel
from storage_flask.baseClasses import db
class TO(DataModel):
__tablename__ = "to"
to_version = db.Column(db.String(100), nullable = False)
title = db.Column(db.String(100), nullable = False)
issue_date = db.Column(db.DateTime, default = datetime.now().date())
change_date = db.Column(db.DateTime, default = datetime.now().date())
def __repr__(self):
return f"TO('{self.own_id}','{self.name}','{self.to_version}','{self.project}','{self.last_user}','{self.issue_date}','{self.change_date}','{self.path}','{self.title}'"
config.py
import os
class BaseConfig:
SECRET_KEY = 'aafa4f8047ce31126011638be8530da6'
SQLALCHEMY_TRACK_MODIFICATIONS = False
class DevelopmentConfig(BaseConfig):
DEBUG = True
#Database
SQLALCHEMY_DATABASE_URL = 'mysql+pymysql://root:demo#localhost:33065/TO'
init.py
import os
from flask import Flask
from storage_flask.baseClasses import db, bcrypt, login_manager, User
from storage_flask.main.routes import main
def create_app(config):
#create app instance
app = Flask(__name__.split('.')[0],static_folder="static")
app.config.from_object(config)
db.init_app(app)
bcrypt.init_app(app)
login_manager.init_app(app)
#register blueprintes
app.register_blueprint(main)
return app
run.py
from storage_flask import create_app, config
app = create_app(config.DevelopmentConfig)
if __name__ == '__main__':
app.run(host="127.0.0.1", debug=True)
routes.py of the blueprint main
from flask import render_template, url_for, flash, redirect, request, make_response, jsonify, abort, send_from_directory, Blueprint
# import flask-login functions
from flask_login import login_user, current_user, logout_user, login_required
main = Blueprint('main',__name__)
#main.route('/', methods = ['POST', 'GET'])
#login_required
def select_function():
return render_template('functionSelect.html', title = 'Function Selection')
The structure of the project would be:
|--storage_flask/
| |--main/
| | |--routes.py
| |--__init__.py
| |--baseClasses.py
| |--config.py
| |--model.py
|--run.py
I tried many ways to debug it but I always get the error. The database exists and it works before refactoring with factory pattern.
Could someone give me a hand?
I am using flask with SQLAlchemy, after set all configuration setting I got db import error on model.
ImportError: cannot import name 'db'
my main app __init__
from flask_api import FlaskAPI
from flask_sqlalchemy import SQLAlchemy
import os
import json
from flask import Flask
from flask_pymongo import PyMongo
from flask import request
from app.test.controllers import test
def create_app(config_name):
app = FlaskAPI(__name__)
CORS(app)
app.config.from_object(os.environ['APP_SETTINGS'])
db = SQLAlchemy(app)
from app.test.controllers import test
app.register_blueprint(test)
my controller and model in app/test/test.py and model.py
test.py
from flask import Blueprint, request, redirect, url_for
import json
from flask_sqlalchemy import SQLAlchemy
from app.test.model import TestModel
test = Blueprint('test', __name__, url_prefix='/api/v1')
#test.route('/test/store', methods=['POST'])
def store():
return json.dumps({'success':True}), 200, {'ContentType':'application/json'}
my model.py
from app import db
class TestModel(db.Model):
__tablename__ = 'user_profiles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), unique=False)
email= db.Column(db.String(255), unique=False)
def __init__(self, name=None, email=None):
self.name = name
self.email = email
def __repr__(self):
return '<User %r>' % (self.name, self.email)
You are using the Flask factory method so initialize SqlAlchemy in your model and import it to your __init__.py file
So model.py becomes
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class TestModel(db.Model):
__tablename__ = 'user_profiles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), unique=False)
email= db.Column(db.String(255), unique=False)
def __init__(self, name=None, email=None):
self.name = name
self.email = email
def __repr__(self):
return '<User %r>' % (self.name, self.email)
Then in __init__.py it becomes
from flask_api import FlaskAPI
from model import db
import os
import json
from flask import Flask
from flask_pymongo import PyMongo
from flask import request
from app.test.controllers import test
def create_app(config_name):
app = FlaskAPI(__name__)
CORS(app)
app.config.from_object(os.environ['APP_SETTINGS'])
db.init_app(app)
from app.test.controllers import test
app.register_blueprint(test)
I'm having trouble creating a modular application using Flask using blueprints. I'm not sure how to migrate models defined in blueprints.
My app looks as follows:
- app
- __init__.py
- user
__init__.py
models.py
app.__init__.py looks as follows:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import Config
from flask_migrate import Migrate
from app.auth import bp as user_bp
db = SQLAlchemy()
app = Flask(__name__)
app.config.from_object(Config)
app.register_blueprint(user_bp, url_prefix='/user')
migrate = Migrate(app, db)
from app.auth.models import User
user/.__init__.py:
from flask import Blueprint
bp = Blueprint('user', __name__)
user/models.py:
from app import db
class User(db.Model):
user_id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(128))
last_name = db.Column(db.String(128))
user_name = db.Column(db.String(120))
password_hash = db.Column(db.String(220))
def __repr__(self):
return '<User {}>'.format(self.email)
When trying to run flask db migrate... no models are being detected and I think I have some sort of circular dependency.
Can someone please explain how to do this properly?
The User model (user/models.py) should be imported somewhere in the application, try to import into the blueprint file (user/__init__.py)
from flask import Blueprint
from app.user.models import User
bp = Blueprint('user', __name__)
app.py
from flask import Flask
from flask_restful import Resource, Api
from user import user_blueprint
from flask_cors import CORS
app = Flask(__name__)
api = Api(app)
app.register_blueprint(user_blueprint)
cors = CORS(app, resources={r"/*": {"origins": "*"}})
if __name__ == '__main__':
app.run(debug=True)
model/user.py
from sqlalchemy import Column, INTEGER, String
class User(Base):
__tablename__ = 'USER'
__table_args__ = {'schema': 'MAPPING'}
ID = Column(INTEGER(11), primary_key=True)
FIRST_NAME = Column(String(255), nullable=False, server_default=text("''"))
LAST_NAME = Column(String(255), nullable=False, server_default=text("''"))
EMAIL = Column(String(255), nullable=False, server_default=text("''"))
route/user_route
from flask import Blueprint, jsonify, request
from flask_restful import Resource, Api
user_blueprint = Blueprint('app/', __name__)
user_api = Api(user_blueprint, prefix='/')
class User(Resource):
def get(self):
db_conn = //db connection Object
results = // your query
db_conn.close()
return jsonify(results)
user_api.add_resource(User, '/user')
I am following this tutorial: getting started with flask-login.
However I am stuck at step 5 where I start to use SQLAlchemy. I believe the problem might be circular importing, based on what I have read but I'm still a little new to Python coding. This web app is a little project I am doing in my free time.
So I guess my overall question is, is this circular importing, and if not does anyone see what I might be doing wrong here? I am also running this using virtualenv using Python 2.7.
File Structure:
-noteapp
-noteapp
-db
-forms
-static
-templates
-views
__init__.py
app.py
models.py
This is my app.py file
from flask import Flask
from flask_login import LoginManager
from noteapp.models import db
from noteapp.views.index import bp as index_bp
from noteapp.views.createnote import bp as createnote_bp
from noteapp.views.signup import bp as signup_bp
def init_db():
db.init_app(app)
db.app = app
db.create_all()
app = Flask(__name__)
app.secret_key = 'removed for reasons'
app.config['SQLALCHEMY_DATABASE_URI'] = 'removed for reasons'
db = SQLAlchemy(app)
login_manager = LoginManager(app)
login_manager.init_app(app)
app.register_blueprint(index_bp)
app.register_blueprint(createnote_bp)
app.register_blueprint(signup_bp)
if __name__ == '__main__':
app.init_db()
app.run(debug=True)
This is my models.py file:
from noteapp.app import app
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class User(db.Model):
email = db.Column(db.String(80), primary_key=True, unique=True)
password = db.Column(db.String(80))
def __init__(self, email, password):
self.email = email
self.password = password
def __repr__(self):
return '<User %r>' % self.email
You are correct you have a circle import issue.
At app.py you import from noteapp.models import db,
and at models.py you import from noteapp.app import app
A quick fix could be:
at models.py use db = SQLAlchemy() without the app.
At the app.py module, import db from models.py and do db.init_app(app)
also remove db = SQLAlchemy(app) from your app.py
your app.py should look like this..
from noteapp.models import db
...
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'removed for reasons'
...
def init_db():
db.init_app(app)
db.app = app
db.create_all()
...
if __name__ == '__main__':
app.init_db()
app.run(debug=True)
models.py should look like this:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
email = db.Column(db.String(80), primary_key=True, unique=True)
password = db.Column(db.String(80))
def __init__(self, email, password):
self.email = email
self.password = password
def __repr__(self):
return '<User %r>' % self.email
This question already has an answer here:
Tyring to set up modelview with Flask-Admin causes ImportError
(1 answer)
Closed 5 years ago.
I have a flask app which I am trying to run. It seems when I run python app.py, there is a circular import of some sort. Here is the code for both my models.py and app.py:
models.py
import datetime
from app import bcrypt, db
class User(BaseModel, db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
email = db.Column(db.String(255), unique=True, nullable=False)
password = db.Column(db.String(255), nullable=False)
registered_on = db.Column(db.DateTime, nullable=False)
admin = db.Column(db.Boolean, nullable=False, default=False)
def __init__(self, email, password, admin=False):
self.email = email
self.password = bcrypt.generate_password_hash(password)
self.registered_on = datetime.datetime.now()
self.admin = admin
app.py
from flask import Flask, render_template
from flask import request, jsonify, session
from flask.ext.bcrypt import Bcrypt
from flask_sqlalchemy import SQLAlchemy
from models import User
app = Flask(__name__)
db = SQLAlchemy()
POSTGRES = {
'user': 'postgres',
'db': 'postgres',
'host': 'localhost',
'port': '5432',
}
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://%(user)s#%(host)s:%(port)s/%(db)s' % POSTGRES
app.config['SECRET_KEY'] = 'lol'
bcrypt = Bcrypt(app)
db.init_app(app)
#app.route('/api/register', methods=['POST'])
def register():
json_data = request.json
user = User(
email=json_data['email'],
password=json_data['password']
)
try:
db.session.add(user)
db.session.commit()
status = 'success'
except:
status = 'this user is already registered'
db.session.close()
return jsonify({'result': status})
manage.py
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from app import app, db
from models import User
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
#manager.command
def create_admin():
"""Creates the admin user."""
db.session.add(User(email='admin#admin.com', password='admin', admin=True))
db.session.commit()
if __name__ == '__main__':
manager.run()
I have played around with the imports but nothing seems to work, I usually will get a circular import error like this:
Traceback (most recent call last):
File "app.py", line 7, in <module>
from models import User
File "/Users/Rishub/Desktop/apps/topten/models.py", line 3, in <module>
from app import bcrypt, db
File "/Users/Rishub/Desktop/apps/topten/app.py", line 7, in <module>
from models import User
ImportError: cannot import name User
Does anyone know the solution to this?
In addition, if I run python manage.py runserver, my app runs fine so I am curious as to why this works but python app.py does not.
in models.py you are importing:
from app import bcrypt, db
in app.py you are importing models.
from models import User
To fix it restructure the program as shown here: http://flask.pocoo.org/docs/0.12/patterns/sqlalchemy/
create a database.py file with database configs etc.
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
def init_db():
import models
Base.metadata.create_all(bind=engine)
use this in models.py as
from database import Base
from sqlalchemy import Column, Integer, String
# instead of db.column directly use Column
class User(Base):
and app files as:
from database import init_db
init_db()
from database import db_session
from models import User
#app.route('/api/register', methods=['POST'])
def register():
json_data = request.json
user = User(
email=json_data['email'],
password=json_data['password']
)
db_session.add(user)
db_session.commit()
return jsonify({'result': 'success'})