sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user - python

i have been getting this error sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user but i dont know why since i created my database at the good directory by the command sqlite3 database.db and .tables .I tried db.create_all() but if it is before the declaration of db it of course not work but if i put it after it does not change anything
I have an other problem which is that db."" is always marked as an error. I tried to install pylint-flask and loading it in the settings. It worked for around 5 mins then the errors are back again (Instance of 'SQLAlchemy' has no 'Column' memberpylint(no-member))
from flask import Flask, render_template, redirect, url_for
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField
from wtforms.validators import InputRequired, Email, Length
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
app = Flask(__name__)
app.config['SECRET_KEY'] = 'Thisissupposedtobesecret!'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sqlite-tools-win32-x86-3290000/database.db'
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(15), unique=True)
email = db.Column(db.String(50), unique=True)
password = db.Column(db.String(80))
#login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class LoginForm(FlaskForm):
username = StringField('username', validators=[InputRequired(), Length(min=4, max=15)])
password = PasswordField('password', validators=[InputRequired(), Length(min=8, max=80)])
remember = BooleanField('remember me')
class RegisterForm(FlaskForm):
email = StringField('email', validators=[InputRequired(), Email(message='Invalid email'), Length(max=50)])
username = StringField('username', validators=[InputRequired(), Length(min=4, max=15)])
password = PasswordField('password', validators=[InputRequired(), Length(min=8, max=80)])

after defining your Model you need to call create_all() to update the changes to the database.
for example..
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(15), unique=True)
email = db.Column(db.String(50), unique=True)
password = db.Column(db.String(80))
db.create_all()

Related

flask sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: users

I keep receiving this error on when trying to launch my application and, despite looking through many Stack overflow posts that had my same error, nothing I tried seems to work.
I have the database existing in my current directory, the databse_uri seems to be correct, I have configured the application before creating the database (db) and I have created the database before connecting to it. What am I doing wrong?
import api_requests #to process the requests from users
#creating the user class
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm #for creating forms through flask
from flask_wtf.file import FileField, FileRequired, FileAllowed
from wtforms import StringField, PasswordField, SubmitField, RadioField #for creating fields in input forms
from wtforms.validators import InputRequired, Length, ValidationError #for validating user input in the forms
from flask_login import UserMixin
app = Flask(__name__)
#app configurations
app.config["SECRET_KEY"]= SECRET_KEY
app.config["MAX_CONTENT_LENGTH"] = 100*1024*1024 #100MB max-limit per image
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] =False
app.config['SQLALCHEMY_DATABASE_URI'] ='sqlite:///Users.db'
bcrypt = Bcrypt(app)
db= SQLAlchemy(app)
login_manager=LoginManager()
login_manager.init_app(app)#will allow flask and login manager to work together when users are logging in
login_manager.login_view ="login"
class Users(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), nullable=False, unique=True)
password = db.Column(db.String(100), nullable=False)
#creating the registration form
class RegisterForm(FlaskForm):
username = StringField(validators=[InputRequired(), Length(min=4, max=100)], render_kw={"placeholder":"Username"})
password = PasswordField(validators=[InputRequired(), Length(min=4, max=100)], render_kw={"placeholder": "password"})
confirm_password = PasswordField(validators=[InputRequired(), Length(min=4, max=100)], render_kw={"placeholder": "confirm_password"})
submit = SubmitField("Register")
def validate_username(self, username):
existing_user_username = Users.query.filter_by(username=username.data).first()
if existing_user_username:
raise ValidationError("That username already exists. Please pick another one.")
#creating the login form
class LoginForm(FlaskForm):
username = StringField(validators=[InputRequired(), Length(min=4, max=100)], render_kw={"placeholder":"Username"})
password = PasswordField(validators=[InputRequired(), Length(min=4, max=100)], render_kw={"placeholder": "password"})
submit = SubmitField("Login")
#creating the upload image form
class UploadImage(FlaskForm):
file = FileField(validators=[FileRequired(), FileAllowed(['png', 'jpeg','jpg'], 'Images only!')]) #allow only files with the correct extension to be submitted
organs = RadioField('Label', choices=[('leaf','leaf'),('flower','flower'),('fruit','fruit'),('bark','bark/stem')])
upload = SubmitField("Upload")
#login_manager.user_loader
def load_user(user_id):
return Users.get(user_id) # loads the user object from the user id stored in the session
#app.route("/new_user", methods=["GET", "POST"])
def register_user():
form = RegisterForm()
if request.method == "POST":
if form.validate_on_submit():
if form.confirm_password.data != form.password.data:
flash("the two password fields don/t match, please enter them correctly")
return render_template('new_user.html', form = form)
hashed_password = bcrypt.generate_password_hash(form.password.data)
new_user = Users(username=form.username.data, password= hashed_password)
db.session.add(new_user)
db.session.commit()
return redirect(url_for("login"))
#insert something here
flash("Username already exists, please pick another one")
return render_template("new_user.html", form=form)
#app.route("/log", methods=["GET", "POST"])
def login():
form = LoginForm()
if form.validate_on_submit():
#check if user is in db
user = Users.query.filter_by(username =form.username.data).first()
if user:
if bcrypt.check_password_hash(user.password,form.password.data):
login_user(user)
return redirect(url_for("view_plants"))
flash("Username or password entered incorrectly. Please try entering them again.")
return render_template("index.html", form=form)
here is my code:
Check your Flask-SQLAlchemy version- you might need to downgrade to 2.5.1.

How does Flush error occur and how do I solve it?

I'm trying to make a login page I have been trying for weeks but this error keeps popping up:
sqlalchemy.orm.exc.FlushError: Instance <Users at 0x10bd8c580> has a NULL identity key.
The error lies in the register.py file. Apparently flask doesn't like me using .commit() or .add(). I've also tried to use .flush
but it gave me the same error still
register.py:
from flask import Blueprint, url_for, render_template, redirect, request
from flask_login import LoginManager
from werkzeug.security import generate_password_hash
import sqlalchemy
from models import db, Users
register = Blueprint('register', __name__, template_folder='../frontend')
login_manager = LoginManager()
login_manager.init_app(register)
#register.route('/register', methods=['GET', 'POST'])
def show():
if request.method == 'POST':
username = request.form['username']
email = request.form['email']
password = request.form['password']
confirm_password = request.form['confirm-password']
if username and email and password and confirm_password:
if password == confirm_password:
hashed_password = generate_password_hash(
password, method='sha256')
try:
new_user = Users(
username=username,
email=email,
password=hashed_password,
)
db.session.add(new_user)
db.session.commit()
except sqlalchemy.exc.IntegrityError:
return redirect(url_for('register.show') + '?error=user-or-email-exists')
return redirect(url_for('login.show') + '?success=account-created')
else:
return redirect(url_for('register.show') + '?error=missing-fields')
else:
return render_template('register.html')
Models.py:
from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Users(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(15), unique=True)
email = db.Column(db.String(50), unique=True)
password = db.Column(db.String)
item = db.Column(db.String(25))
amount = db.Column(db.Integer)
I'm still a beginner with flask so excuse me if it's real obvious, any assistance would be very welcome!
You didn't specify what sql database you are using with sqlAlchemy. Anyways, the id is not being generated so the new_user has no identity. that's why your getting this error. To solve the problem modify your model as follows:
class Users(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(15), unique=True)
email = db.Column(db.String(50), unique=True)
password = db.Column(db.String)
item = db.Column(db.String(25))
amount = db.Column(db.Integer)
or you can use Sequence instead of autoincrement:
id = db.Column(db.Integer, primary_key=True, Sequence('user_seq'))
This is for the identity issue, but note that you need to specify user_loader for flask_login to work.

Flask sqlalchemy, delete user returns Object is already attached to session '9' (this is '10')

I am trying to add delete user function to admin dashboard, now if i try to delete any user i get this error:
sqlalchemy.exc.InvalidRequestError: Object '<User at 0x29859f359a0>' is already attached to session '9' (this is '10')
models.py:
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
db = SQLAlchemy()
class User(UserMixin, db.Model):
"""User Model"""
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(25), unique=True, nullable=False)
password = db.Column(db.String(8), nullable=False)
role = db.Column(db.String(25), nullable=False)
main.py:
import time
import os
import random
from cryptography.fernet import Fernet
from flask import Flask, render_template, url_for, session, redirect, flash
from flask_socketio import SocketIO, send, leave_room, join_room
from wtf_forms import *
from models import *
from passlib.hash import pbkdf2_sha256
from flask_login import LoginManager, login_user, current_user, login_required, logout_user
# DATA BASE
app.config['SQLALCHEMY_DATABASE_URI'] = 'link'
db = SQLAlchemy(app)
# Configure flask login
login = LoginManager(app)
login.init_app(app)
#socketio.on('delete_user')
def on_delete(data):
""" delete user or admin"""
if data:
username, role = data['user'].split('_')
user = User.query.filter_by(username=username).first()
if user:
db.session.delete(user)
db.session.commit()
print('user deleted')
else:
print('user not deleted')
now how can i delete users from db successfully, and avoid getting this erro in the future.

sqlalchemy.exc.OperationalError (No such coumn) in flask framework

I want to add images on my flaskblog posts, however, I am facing with the following error:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: post.post_image
[SQL: SELECT post.id AS post_id, post.title AS post_title, post.date_posted AS post_date_posted, post.content AS post_content, post.user_id AS post_user_id, post.post_image AS post_post_image
FROM post]
(Background on this error at: http://sqlalche.me/e/e3q8)
These are my imports in routes.py file
import os
import secrets
from PIL import Image
from flask import render_template, url_for, flash, redirect, request, abort
from flaskblog import app, db, bcrypt
from flaskblog.forms import RegistrationForm, LoginForm, UpdateAccountForm, PostForm
from flaskblog.models import User, Post
from flask_login import login_user, current_user, logout_user, login_required
This is my new_post function and new post route in routes.py file
#app.route("/post/new", methods=['GET', 'POST'])
#login_required
def new_post():
form = PostForm()
if form.validate_on_submit():
if form.post_picture.data:
image_post = save_picture(form.picture.data)
form.post_picture = image_post
post = Post(title=form.title.data, content=form.content.data, author=current_user, post_image= form.post_picture.data)
db.session.add(post)
db.session.commit()
flash('Your post has been created!', 'success')
return redirect(url_for('home'))
image_file = url_for('static', filename='profile_pics/')
return render_template('create_post.html', title='New Post', image_file=image_file,
form=form, legend='New Post')
This is my imports in form.py file
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from flask_login import current_user
from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from flaskblog.models import User
this is my PostForm class in forms.py file
from datetime import datetime
from flaskblog import db, login_manager
from flask_login import UserMixin
#login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')"
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
post_image = db.Column(db.String(20), nullable=False)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
regarding these codes, what do you think I should do in order to fix this error? Thank you.
edit1:
This is my init.py file
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
app = Flask(__name__)
app.config['SECRET_KEY'] = '5791628bb0b13ce0c676dfde280ba245'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
from flaskblog import routes
edit2: I am having the following error after dropping tables from the db.
This is the blog post view
Have you newly added the post_image field to the Post model?
If so, you'd need to either
use a database migration tool like Alembic to generate and apply the SQL statements to alter the table, or
add the suitable column into the table by hand (tedious), or
drop the table and recreate it (destroying all data; dangerous)

Error "NameError: name 'UsersAdmin' is not defined" when moved all classes to another file

Short story. I took this example:https://github.com/MrJoes/Flask-Admin/tree/master/examples/sqla i played with it and everything was fine until i decided what i want to split app.py(main file) to two parts. In main file app.py i will keep views and in another models.py i will keep all classes. Both files are in same folder.
Issue. I get error Error when running my app.py file:
"NameError: name 'UserAdmin' is not defined"
This is part from app.py file where i try to call Class UserAdmin from models.py file:
import os
import os.path as op
from flask import Flask, render_template, request, redirect, url_for, abort, session, flash
from flask_sqlalchemy import SQLAlchemy, Model
from flask_login import UserMixin, session, LoginManager, login_user, login_required, logout_user
from flask_bcrypt import Bcrypt,check_password_hash,generate_password_hash
from models import *
from flask_admin import Admin, BaseView, expose
app = Flask(__name__)
app.config['SECRET_KEY'] = '123456790'
app.config['DATABASE_FILE'] = 'db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
admin = Admin(app, name='Admin Site', template_mode='bootstrap3')
# Add views. This is where it fails
admin.add_view(UserAdmin(User, db.session))
models.py file where is described UserAdmin part:
from wtforms import validators
from app import db, app, url_for, admin
from flask_admin.contrib import sqla
from flask_admin.contrib.sqla import filters, ModelView
from flask_login import UserMixin
...
# Create models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(100))
last_name = db.Column(db.String(100))
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
# Required for administrative interface. For python 3 please use __str__ instead.
def __str__(self):
return self.username
class UserInfo(db.Model):
id = db.Column(db.Integer, primary_key=True)
key = db.Column(db.String(64), nullable=False)
value = db.Column(db.String(64))
user_id = db.Column(db.Integer(), db.ForeignKey(User.id))
user = db.relationship(User, backref='info')
def __str__(self):
return '%s - %s' % (self.key, self.value)
class UserAdmin(sqla.ModelView):
inline_models = (UserInfo,)
...
If someone could point me what i am doing wrong there it would be very nice.
Thanks

Categories