SQLAlchemy OperationalError no such table - confusion with sqlite uri - python

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!

Related

flask_sqlalchemy query returns ImportError

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?

SQLAlchemy OperationalError no such table

I am creating a Flask app, and I have a page with a form to register new users. But when I type some data, I get the error sqlalchemy.exc.OperationalError: (OperationalError) no such table: user. In the file config.py I have this line
SQLALCHEMY_DATABASE_URI = "sqlite:///example.sqlite" and this is the rest of my code:
flask_start.py
import os
from flask import Flask
from config import Config
from flask_utils import page_bp
from db_creation import db
def create_app():
appname = "IOT - PROJECT NASTIS"
app = Flask(appname)
myconfig = Config
app.config.from_object(myconfig)
app.register_blueprint(page_bp, url_prefix='')
db.init_app(app)
return app
def setup_database(app):
with app.app_context():
db.create_all()
if __name__ == "__main__":
app = create_app()
if not os.path.isfile('/tmp/test.sqlite'):
setup_database(app)
port = 8000
interface = '0.0.0.0'
app.run(host=interface, port=port, debug=True)
db_creation.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
flask_utils.py
db_creation import db
from User import User
page_bp = Blueprint("page_bp", __name__)
#page_bp.route('/mainPage/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm(request.form)
if request.method == 'POST' and form.validate():
user = User(form.username.data, form.email.data,
sha256_crypt.encrypt(str(form.password.data)))
db.session.add(user)
db.session.commit()
flash('Thanks for registering, you can now log in!!', 'success')
return redirect(url_for('page_bp.register'))
return render_template('register.html', form=form)
User.py
from db_creation import db
class User(db.Model):
username = db.Column(db.String(100), primary_key=True)
email = db.Column(db.String(100))
password = db.Column(db.String(100))
def __init__(self, username, email, password):
self.username = username
self.email = email
self.password = password
What am I doing wrong? I can't figure out what is the mistake
When you run db.create_all() it needs to know which tables to create-- it can tell that by which models it currently can see.
User isn't imported in your start_flask.py file-- so when db.create_all() is run it pretty much goes 'huh, I'm not aware of any models, I guess I'll just create an empty database with no tables' it doesn't know to go and look in other files, so you just need to introduce them :)
Adding from User import User to the imports in the start_flask.py file should solve that.
Also-- you're checking for a file in /tmp/... to trigger your 'no database file yet' check, but your SQLALCHEMY_DATABASE_URI isn't matching that.

'scoped_session' object has no attribute 'create_all' 'scoped_session' object has no attribute 'session'

So Im trying to create a website using flask and SQLAlchemy for database storage but I keep getting the two aforementioned errors
Here is my app.py code
import os
from flask import Flask, session,render_template, request
from flask_session import Session
from sqlalchemy import create_engine,Column, Integer, String
from sqlalchemy.orm import scoped_session, sessionmaker
from flask_sqlalchemy import SQLAlchemy
from models import *
app = Flask(__name__)
#app.config["DATABASE_URL"] = "sqlite:////plz_work.db"
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URL")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
# Check for environment variable
#if not os.getenv("DATABASE_URL"):
# raise RuntimeError("DATABASE_URL is not set")
# Configure session to use filesystem
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Set up database
engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))
class User:
def __init__(self,username,password):
self.username = username
self.password = password
#app.route("/")
def index():
return render_template('index.html')
#app.route("/registration.html")
def registration():
return render_template('registration.html')
#app.route("/send", methods = ['GET','POST'])
def send():
username = request.form['username']
password = request.form['password']
users = User(username,password)
db.session.add(users)
db.session.commit()
return render_template('index.html')
if __name__ == "__main__":
app.run(debug = True)
db.create_all()
and here is my models.py file
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class USERS(db.Model):
__tablename__ = "Users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String)
password = db.Column(db.String)
def __repr__(self):
value = "USER:({}, {})".format(self.username, self.password)
return value
I have been looking online for a soloution for so long but I can not find anything that works for me, and I have spent 2 days just on this problem, any help will be appreciated.
Thank You !!
I guess you're overriding your database object within your models.py file.
I suggest you to use sqlalchemy itself or flask-sqlalchemy not using them together. In my opinion things get complicated if you use them together.
You can achive that like this:
in your app.py
...your_other_imports...
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from .models import *
app = Flask(__name__)
...your_other_configs...
# Set up database
engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))
#NOW db carries your database session
#Do not define your database models in app.py remove User class from here.
#You should define your database model and also your query method (not necessary)
#if you're used to query with flask-sqlalchemy. Would make queries look similar to you
dbModel = declarative_base()
dbModel.query = db.query_property()
# define the function which will create your tables
def init_db():
from .models import *
dbModel.metadata.create_all(bind=engine)
...your_routes...
if __name__ == "__main__":
app.run(debug = True)
# now call the function to create your tables
init_db()
in your models.py
from .app import dbModel
from sqlalchemy import Column, Integer, String
class User(dbModel):
__tablename__ = "users"
id = Columnn(Integer, primary_key=True)
username = Column(String)
password = Column(String)
def __repr__(self):
value = "USER:({}, {})".format(self.username, self.password)
return value
Using query_property you can now query your data from your database and use your session to put data in your database like this:
User.query.filter_by(username=...).first()
newUser = User(
username=...,
password=...
)
db.add(newUser)
db.commit()

Flask - SQLAlchemy OperationalError

I've come into the following error:
sqlalchemy.exc.OperationalError
OperationalError: (OperationalError) no such table: user u'SELECT user.id AS user_id, user.name AS user_name, user.password AS user_password \nFROM user \nWHERE user.id = ?' (1,)
I'm not sure how to debug this but I think it must be coming because its not loading the db file that I already generated using my models.py file. I've loaded that db file and made sure that the users table exists, and it does with data, but I can't figure out how to connect my flask application to the database.
Here's my models.py that I ran beforehand to generate the tables (I haven't included the declarations above it):
from datetime import datetime
import os
from sqlalchemy import Column, ForeignKey
from sqlalchemy import Boolean, DateTime, Integer, String, Text
from sqlalchemy.orm import relationship, synonym, backref
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
""" User """
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(200))
password = Column(String(100))
def __init__(self, name, password):
self.name = name
self.password = password
def __repr__(self):
return '<User %r>' % self.name
if __name__ == '__main__':
from datetime import timedelta
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
PWD = os.path.abspath(os.curdir)
engine = create_engine('sqlite:///{}/arkaios.db'.format(PWD), echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# Add a sample user
user = User(name='Philip House', password="test")
session.add(user)
session.commit()
Here's app.py:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask import render_template
from arkaios.models import Base, User
from arkaios import config
app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)
db.Model = Base
#app.route('/admin/large-group')
def largeGroupOverview():
user = db.session.query(User).filter_by(id=1)
return render_template('largegroup/overview.html', user=user)
#app.route('/admin/large-group/<int:event_id>')
def largeGroupAttendance(event_id):
return render_template('largegroup/attendance.html')
#app.route('/focus')
def largegroup():
return 'Focus work'
And finally, app.py refers to config.py which is below:
import os
PWD = os.path.abspath(os.curdir)
DEBUG=True
SQLALCHEMY_DATABASE_URI = 'sqlite:///{}/arkaios.db'.format(PWD)
SECRET_KEY = 'thisissecret'
SESSION_PROTECTION = 'strong'
I can post the stack trace as well if need be! There must be something missing conceptually about how I'm thinking about how to connect Flask and SQLAlchemy, but I can't figure it out.
Thanks for any help :)
Are you running python models.py before python app.py app to create the database? The if __name__ == "__main__" will keep that part of the code from running when you import the file from app.py.
I would also make sure the db is valid using sqlite3 and run the .tables command.

SQLAlchemy create_all() does not create tables

I'm trying to integrate PostgreSQL and SQLAlchemy but SQLAlchemy.create_all() is not creating any tables from my models.
My code:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://login:pass#localhost/flask_app'
db = SQLAlchemy(app)
db.create_all()
db.session.commit()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
admin = User('admin', 'admin#example.com')
guest = User('guest', 'guest#example.com')
db.session.add(admin)
db.session.add(guest)
db.session.commit()
users = User.query.all()
print users
But I get this error: sqlalchemy.exc.ProgrammingError: (ProgrammingError) relation "user" does not exist
How can I fix this?
You should put your model class before create_all() call, like this:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://login:pass#localhost/flask_app'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
with app.app_context():
db.create_all()
db.session.add(User('admin', 'admin#example.com'))
db.session.add(User('guest', 'guest#example.com'))
db.session.commit()
users = User.query.all()
print(users)
If your models are declared in a separate module, import them before calling create_all().
Say, the User model is in a file called models.py,
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://login:pass#localhost/flask_app'
db = SQLAlchemy(app)
# See important note below
from models import User
with app.app_context():
db.create_all()
db.session.add(User('admin', 'admin#example.com'))
db.session.add(User('guest', 'guest#example.com'))
db.session.commit()
users = User.query.all()
print(users)
Important note: It is important that you import your models after initializing the db object since, in your models.py you also need to import the db object from this module.
If someone is having issues with creating tables by using files dedicated to each model, be aware of running the "create_all" function from a file different from the one where that function is declared.
So, if the filesystem is like this:
Root
--app.py <-- file from which app will be run
--models
----user.py <-- file with "User" model
----order.py <-- file with "Order" model
----database.py <-- file with database and "create_all" function declaration
Be careful about calling the "create_all" function from app.py.
This concept is explained better by the answer to this thread posted by #SuperShoot
This is probably not the main reason why the create_all() method call doesn't work for people, but for me, the cobbled together instructions from various tutorials have it such that I was creating my db in a request context, meaning I have something like:
# lib/db.py
from flask import g, current_app
from flask_sqlalchemy import SQLAlchemy
def get_db():
if 'db' not in g:
g.db = SQLAlchemy(current_app)
return g.db
I also have a separate cli command that also does the create_all:
# tasks/db.py
from lib.db import get_db
#current_app.cli.command('init-db')
def init_db():
db = get_db()
db.create_all()
I also am using a application factory.
When the cli command is run, a new app context is used, which means a new db is used. Furthermore, in this world, an import model in the init_db method does not do anything, because it may be that your model file was already loaded(and associated with a separate db).
The fix that I came around to was to make sure that the db was a single global reference:
# lib/db.py
from flask import g, current_app
from flask_sqlalchemy import SQLAlchemy
db = None
def get_db():
global db
if not db:
db = SQLAlchemy(current_app)
return db
I have not dug deep enough into flask, sqlalchemy, or flask-sqlalchemy to understand if this means that requests to the db from multiple threads are safe, but if you're reading this you're likely stuck in the baby stages of understanding these concepts too.

Categories

Resources