flask_sqlalchemy query returns ImportError - python

I have a Flask web application that has an sqlite database called data.db which contains the data of user/admin. Whenever I try to query the data on my python file routes.py it returns an ImportError message. However, when I query the data from my conda terminal it works properly, I got the desired result. Is there's any solution for this? I wonder what I did wrong
this is the init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_bcrypt import Bcrypt
app = Flask(__name__)
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'admin_login'
app.config['SECRET_KEY'] = 'my secret key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
from yves_letters import routes
this is the models.py
from yves_letters import db
from flask_login import UserMixin
class Admin(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True)
display_name = db.Column(db.String(20))
password = db.Column(db.String(100), nullable=False)
def __repr__(self):
return f'id: {self.id}, username: {self.username}, display_name: {self.display_name}, password: {self.password}'
this is the routes.py
from yves_letters.models import Data, Admin
#app.route('/')
def home():
admin = Admin.query.all()
return render_template('home.html')
this is the error I'm getting while running the code
ImportError
ImportError: DLL load failed: The specified module could not be found.
Traceback (most recent call last)
File "C:\Users\USER\anaconda3\envs\webapp_env\lib\site-packages\sqlalchemy\util\_collections.py", line 1020, in __call__
Open an interactive python shell in this framereturn self.registry[key]
On the other hand, when I do the query from my conda terminal it's working well.
admin = Admin.query.all()
admin
[id: 1, username: admin, display_name: Mac Yves]
Is there's something I missed?

Related

When I inherit sqlalchemy (flask app) in a class, it doesn't recognize functions such as Column()

I've been building a Flask app with the help of this video:
https://www.youtube.com/watch?v=dam0GPOAvVI&t=3256s
Here is the file of my init so far :
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
DB_NAME = "database.db"
db = SQLAlchemy()
app = Flask(__name__)
app.config['SECRET_KEY'] = 'bindthemostselling'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
from views import views
from auth import auth
app.register_blueprint(views, url_prefix='/')
app.register_blueprint(auth, url_prefix='/')
if __name__ == '__main__':
app.run(debug=True)
and here is the file of my models so far its just one class:
from flask_login import UserMixin
from . import db
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
first_name = db.Column(db.String(150))
My problem is that the db.Column inside the User class is unrecognizable. I've tried to reinstall sqlalchemy and flask and i've looked at everything he did again and even copied the code from his github and it still wont recognize that function or even other functions that I have noticed so far from the video. This is the first time I try to make an actual python app so maybe there is something i'm missing in the syntax?
Thanks in advance.
EDIT:
So i have updated the init file to include everything so i can run and see what error i get here is what I have now:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
from models import User
from flask_login import LoginManager
DB_NAME = "database.db"
db = SQLAlchemy()
app = Flask(__name__)
app.config['SECRET_KEY'] = 'bindthemostselling'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
from views import views
from auth import auth
app.register_blueprint(views, url_prefix='/')
app.register_blueprint(auth, url_prefix='/')
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
def create_database(app):
if not path.exists('.' + DB_NAME):
db.create_all(app=app)
print('Created Database!')
create_database(app)
if __name__ == '__main__':
app.run(debug=True)
Here is the traceback that I got (Sorry if the formatting is bad):
Traceback (most recent call last):
File "c:\Users\Ashraf\FlaskToDo_init_.py", line 4, in
from models import User
File "c:\Users\Ashraf\FlaskToDo\models.py", line 2, in
from . import db
ImportError: attempted relative import with no known parent package
so apparently the db is not imported correctly? This can't be true cause when I created the User class and passed the db.Model, it recognized it. What am I exactly missing here?
Try changing the import statement in the models file from
from . import db
to:
from init import db
This way you should get a circular import error, so move from models import User in your init after db is defined.
This is the complete setup:
init:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
from flask_login import LoginManager
DB_NAME = "database.db"
db = SQLAlchemy()
app = Flask(__name__)
app.config['SECRET_KEY'] = 'bindthemostselling'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
def create_database(app):
if not path.exists('.' + DB_NAME):
db.create_all(app=app)
print('Created Database!')
create_database(app)
if __name__ == '__main__':
app.run(debug=True)
from models import User
models:
from flask_login import UserMixin
from init import db
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
first_name = db.Column(db.String(150))
EDIT:
add a route to actually navigate in your app:
#app.route("/")
def home():
return "Hello World"

SQLAlchemy OperationalError no such table - confusion with sqlite uri

Help!
I'm really new to flask and I've been muddling along with all the tutorials I could find but I've run into a problem I can't figure out.
Here's my error:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: User
[SQL: SELECT "User"."userId" AS "User_userId", "User".email AS "User_email", "User".password AS "User_password", "User".username AS "User_username", "User".lastlogin AS "User_lastlogin", "User".isauthenticated AS "User_isauthenticated"
FROM "User"
WHERE "User".email = ?
LIMIT ? OFFSET ?]
[parameters: ('test#example.com', 1, 0)]
(Background on this error at: http://sqlalche.me/e/13/e3q8)
So I'm working on the signup form and I've solved all the other bugs. But here what I can make out from this error is that my database or table isn't being created.
Here's my code:
init.py:
import os
from flask import Flask, render_template, redirect, session
from flask_login import LoginManager
from flask_bcrypt import Bcrypt
from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import import_string
from complete.app import redirect_url
db = SQLAlchemy()
login_manager = LoginManager()
def create_app():
"""Create Flask application."""
app = Flask(__name__, instance_relative_config=False)
#app.context_processor
def inject_global_vars():
return dict(appname="Ebay Listing Viewer")
app.config.from_pyfile('configfile.py')
db.init_app(app)
login_manager.init_app(app)
with app.app_context():
from .userauth.auth import auth_bp
app.register_blueprint(auth_bp)
db.create_all()
from .models import User
#login_manager.user_loader
def load_user(user_id):
return User.get(user)
return app
models.py:
"""Data Models"""
from flask_login import UserMixin
from . import db
class User(UserMixin, db.Model):
__tablename__ = 'User'
userid = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(200))
username = db.Column(db.String(1000))
lastlogin = db.Column(db.DateTime)
isauthenticated = db.Column(db.Boolean, default=False)
def is_active(self):
return True
def get_id(self):
return chr(self.userId)
def is_authenticated(self):
return self.isauthenticated
def is_anonymous(self):
return False
def __repr__(self):
return '<User> {}'.format(self.username)
def set_password(self, password):
self.password = generate_password_hash(
password,
method='sha256'
)
def check_password(self, password):
return check_password_hash(self.password, password)
config.py:
class Config(object):
"""Base config."""
SECRET_KEY = environ.get('SECRET_KEY')
STATIC_FOLDER = 'static'
TEMPLATES_FOLDER = 'templates'
class DevelopmentConfig(Config):
FLASK_ENV = 'development'
SQLALCHEMY_DATABASE_URI = environ.get('DEV_DATABASE_URI')
.env:
#among other things...
DEV_DATABASE_URI=sqlite:///db.sqlite
There is a file called db.sqlite in my root folder (ie the same directory as init.py) but I'm not sure it's got anything in it. When I try to open it, it shows The file is not displayed in the editor because it is either binary or uses an unsupported text encoding. (I'm using VSCode).
I'm not quite sure how the database uri works - I've had a lot of looks around Google and everyone seems to think it's completely obvious. Is it the file path to my database file? Do I create the database file or is it automatically created?
I'm thinking the problem is likely to be that the database uri is wrong, but I dunno, I haven't got enough experience so maybe it's something completely different.
Thank you for taking the time to read and help!

(Flask) Heroku Error: sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateTable) relation "user" already exists

I want to update my database tables in heroku. However, when I check the status of my tables using heroku pg:info DATABASE, I realize there are no tables created, yet they are defined in models.py as seen at the bottom of the question.
=== DATABASE_URL
Plan: Hobby-dev
Status: Available
Connections: 0/20
PG Version: 12.4
Created: 2020-10-13 23:10 UTC
Data Size: 8.2 MB
Tables: 0 # <---------------------------no tables
Rows: 0/10000 (In compliance)
Fork/Follow: Unsupported
Rollback: Unsupported
Continuous Protection: Off
Add-on: postgresql-closed-00235
This is how my Python Flask app is set up:
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
MAIL_SERVER='smtp.gmail.com'
MAIL_PORT=587
MAIL_USE_TLS=1
MAIL_USERNAME='my-username'
MAIL_PASSWORD='my-password'
ADMINS=['admin-email']
POSTS_PER_PAGE=10
STRIPE_PUBLISHABLE_KEY='<stripe-publishable-key>'
STRIPE_SECRET_KEY='<stripe-secret-key>'
STRIPE_ENDPOINT_SECRET='<stripe-endpoint-secret>'
LOG_TO_STDOUT = os.environ.get('LOG_TO_STDOUT')
__init__.py
from flask import Flask
from config import Config
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from flask_mail import Mail
from flask_moment import Moment
import stripe
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
login = LoginManager(app)
login.login_view = 'login'
bootstrap = Bootstrap(app)
mail = Mail(app)
moment = Moment(app)
stripe_keys = {
'secret_key': app.config['STRIPE_SECRET_KEY'],
'publishable_key': app.config['STRIPE_PUBLISHABLE_KEY'],
'endpoint_secret': app.config['STRIPE_ENDPOINT_SECRET']
}
stripe.api_key = stripe_keys['secret_key']
if not app.debug:
if app.config['MAIL_SERVER']:
auth = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
secure = None
if app.config['MAIL_USE_TLS']:
secure = ()
mailhandler = SMTPHandler(
mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
fromaddr='noreply#' + app.config['MAIL_SERVER'],
toaddrs=app.config['ADMINS'],
subject='Somasoma: Error',
credentials=auth, secure=secure
)
mailhandler.setLevel(logging.ERROR)
app.logger.addHandler(mailhandler)
if app.config['LOG_TO_STDOUT']:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
app.logger.addHandler(stream_handler)
else:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/somasoma.log', maxBytes=10240, backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d] '
))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('Somasoma Blog')
from app import routes, models, errors
blog_app.py
from app import app, db
from app.models import User, Post
#app.shell_context_processor
def make_shell_context():
return {'db':db, 'User': User, 'Post': Post}
Procfile
web: flask db upgrade; gunicorn blog_app:app
Ideally, to update my database, I have run heroku run flask db upgrade command. This instead throws me this error:
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateTable) relation "user" already exists
[SQL:
CREATE TABLE "user" (
id SERIAL NOT NULL,
username VARCHAR(64),
email VARCHAR(120),
password_hash VARCHAR(128),
about_me VARCHAR(140),
last_seen TIMESTAMP WITHOUT TIME ZONE,
PRIMARY KEY (id)
)
The thing is when I try to log into my deployed up on heroku, I cannot sign up or sign in because of non-existent 'user' as seen in the stdout heroku log:
psycopg2.errors.UndefinedTable: relation "user" does not exist
2020-10-13T23:27:13.018103+00:00 app[web.1]: LINE 2: FROM "user"
SQL: SELECT "user".id AS user_id, "user".username AS user_username, "user".email AS user_email, "user".password_hash AS user_password_hash
2020-10-13T23:27:13.018113+00:00 app[web.1]: FROM "user"
2020-10-13T23:27:13.018114+00:00 app[web.1]: WHERE "user".username = %(username_1)s
2020-10-13T23:27:13.018114+00:00 app[web.1]: LIMIT %(param_1)s]
2020-10-13T23:27:13.018114+00:00 app[web.1]: [parameters: {'username_1': 'harry', 'param_1': 1}]
2020-10-13T23:27:13.018114+00:00 app[web.1]: (Background on this error at: http://sqlalche.me/e/f405)
This error is a direct result of the database tables being empty. I have looked at several example solutions such as this and this but I am not quite able to solve the database issue I am facing.
Personally, I thought that the inclusion of the argument db while instantiating the migrate variable in __init__.py would solve that. I mean:
Instead of:
migrate = Migrate(app)
Then this should fix it:
migrate = Migrate(app, db)
However, with that addition, I am still not able to fix this error.
What could I be missing out on? Any lead or direction is much appreciated.
Edited:
I have a user and post model defined for my database:
models.py
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))
posts = db.relationship('Post', backref = 'author', lazy = 'dynamic')
def __repr__(self):
return '<User {}>'.format(self.username)
class Post(db.Model):
id = db.Column(db.Integer, primary_key = True)
body = db.Column(db.String(140))
timestamp = db.Column(db.DateTime, index = True, default = datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return 'Post <>'.format(self.body)
#login.user_loader
def load_user(id):
return User.query.get(int(id))
This happened because you have dropped the alembic_version table.
It can be rectified in your project's Procfile. Open your Procfile, copy and paste this code snippet:
release: flask db upgrade
release: flask db stamp head
web: gunicorn app:app

AttributeError when importing flask-SQLAlchemy model

I am following this tutorial to build a JWT based authentication system.
app.py:
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'd0cad49580952003e6ae01499c7bb190a4b4f9a5babd866f47064707f7b78506'
api = Api(app)
db = SQLAlchemy(app)
#app.before_first_request
def create_tables():
db.create_all()
import resources, models
api.add_resource(resources.UserRegistration, '/registration')
if __name__ == '__main__':
app.run()
models.py:
from app import db
class UserModel(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(150), nullable=False)
email = db.Column(db.String(100), unique=True, nullable=False)
def __init__(self, name, password, email):
self.name = name
self.password = password
self.email = email
#classmethod
def find_by_username(cls, username):
return cls.query.filter_by(username=username).first()
def save_to_db(self):
db.session.add(self)
db.session.commit()
resources.py:
from flask_restful import Resource, reqparse
from models import UserModel
class UserRegistration(Resource):
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('name', help='This field cannot be blank', required=True)
parser.add_argument('email', help='This field cannot be blank', required=True)
parser.add_argument('password', help='This field cannot be blank', required=True)
data = parser.parse_args()
if UserModel.find_by_username(data['name']):
return {'message': 'User {} already exists'.format(data['name'])}
new_user = UserModel(
name=data['name'],
password=data['password'],
email=data['email']
)
try:
new_user.save_to_db()
return {
'status': 'User {} was created'.format(data['username'])}
except:
return {'message': 'Something went wrong'}, 500
When I run app.py, I get the following error:
Traceback (most recent call last):
File "G:\python\PycharmProjects\vumonic\app.py", line 19, in <module>
import resources, models
File "G:\python\PycharmProjects\vumonic\resources.py", line 2, in <module>
from models import UserModel
File "G:\python\PycharmProjects\vumonic\models.py", line 1, in <module>
from app import db
File "G:\python\PycharmProjects\vumonic\app.py", line 21, in <module>
api.add_resource(resources.UserRegistration, '/registration')
AttributeError: module 'resources' has no attribute 'UserRegistration'
This error dissapears when I remove from models import UserModel from resources.py.
I cannot figure out the reason for the error.
I am using Flask==1.1.2, Flask-SQLAlchemy==2.4.4 and Flask-RESTful==0.3.8
This is the first time Iam developing an API so any help would be appreciated.
you are facing circular import issue.
When Python imports a module, it checks the module registry to see if the module was already imported. If the module was already registered, Python uses that existing object from cache. The module registry is a table of modules that have been initialized and indexed by module name. This table can be accessed through sys.modules.
If it was not registered, Python finds the module, initializes it if necessary, and executes it in the new module's namespace.
to know more about circular import you can read the article:
https://stackabuse.com/python-circular-imports/
https://www.stefaanlippens.net/circular-imports-type-hints-python.html
this tutorial of Miguel Grinberg is a life savior
https://www.youtube.com/watch?v=NH-8oLHUyDc&t=3205s

Flask directory Structure

I have flask project which work on presently. (below)
When I run this project using command
python run.py
I get following error.
Traceback (most recent call last):
File "run.py", line 1, in
from site import app
ImportError: cannot import name 'app'
run.py
from site import app
import os
app.secret_key = os.urandom(24)
port = int(os.environ.get('PORT', 5000))
if __name__ == '__main__':
app.run(debug="True")
# app.run(host='0.0.0.0', port=port)
__init__.py
from .views import app
from .models import db
db.create_all()
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:password#localhost:5432/db'
app.config['SECURITY_REGISTERABLE'] = True
views.py
from flask import Flask
from .models import User, db
from flask import render_template, request, redirect, url_for
from flask.ext.security import login_required
app = Flask(__name__, static_url_path='')
#app.route('/')
def index():
return render_template('index.html')
#app.route('/profile/<email>')
#login_required
def user_index(email):
user = User.query.filter_by(email=email).first()
return render_template('profile.html', user=user)
#app.route('/post_user', methods=['POST'])
def post_user():
if request.form["action"] == "submit_btn":
user = User(request.form['username'], request.form['email'])
db.session.add(user)
db.session.commit()
return redirect(url_for('index'))
models.py
from flask import Flask
from flask.ext.mail import Mail, Message
from flask_sqlalchemy import SQLAlchemy
from flask.ext.security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin
app = Flask(__name__, static_url_path='')
db = SQLAlchemy(app)
mail = Mail()
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
password = db.Column(db.String(255))
active = db.Column(db.Boolean())
confirmed_at = db.Column(db.DateTime())
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
What should be the directory structure? Also how should I import the models and views in order to make the server work?
Please tell me if you need any other info, thanks in advance.
Rename the site's name so python dont try to import the site standard library, also is better to define the app inside the init.py file: Docs

Categories

Resources