SQLAlchemy and flask (sqlalchemy.exc.OperationalError:) - python

I've got this message:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user
[SQL: INSERT INTO user (username, email, password) VALUES (?, ?, ?)]
[parameters: ('test', 'test#test.com', 'password')]
(Background on this error at: http://sqlalche.me/e/e3q8)
when I tried: db.session.commit(). I'm following a tutorial and try to personalize the code but with bad results.
What I did so far is:
>>> from lagerut import db
>>> db.create_all()
>>> from models import User
>>> user_1 = User(username='test', email='test#test.com', password='password')
>>> db.session.add(user_1)
>>> db.session.commit()
Here the lagerut.py:
from datetime import datetime
from flask import Flask, render_template, url_for, flash, redirect
from flask_sqlalchemy import SQLAlchemy
from form import RegistrationForm, LoginForm
app = Flask(__name__)
app.config['SECRET_KEY'] = '2a1de6eea4126191912d6e702c6aa8f9'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///lagerut.db'
db = SQLAlchemy(app)
#app.route('/')
#app.route('/home')
def home():
return render_template ('home.html')
#app.route('/how-it-works')
def howitworks():
return render_template ('how-it-works.html', title='How it works')
#app.route('/lager-out')
def lagerout():
return render_template ('lager-out.html', title='Lager out')
#app.route('/lager-in')
def lagerin():
return render_template ('lager-in.html', title='Lager in')
#app.route("/register", methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
flash(f'Account created for {form.username.data}!', 'success')
return redirect(url_for('home'))
return render_template('register.html', title='Register', form=form)
#app.route("/login", methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
if form.email.data == 'admin#blog.com' and form.password.data == 'password':
flash('You have been logged in!', 'success')
return redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check username and password', 'danger')
return render_template('login.html', title='Login', form=form)
if __name__ == '__main__':
app.run(debug=True)
And here the models.py:
from datetime import datetime
from lagerut import db
class User(db.Model):
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)
password = db.Column(db.String(60), nullable=False)
def __repr__(self):
return f"User('{self.username}', '{self.email}')"
class Items(db.Model):
item_number = db.Column(db.Integer, primary_key=True)
description = db.Column(db.String(200), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
department = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
def __repr__(self):
return f"Items('{self.product}', '{self.date_posted}', '{self.content}', '{self.department}', '{self.content}')"
Should I try to write the code again? I'm just trying to learn how build a little app to my work.
Is a good way to learn programming works also with the shell?

That's because you are not creating the app context while creating the database since you are doing this via python shell you need to add the following line
with app.app_context():
Read more about this here https://flask.palletsprojects.com/en/1.0.x/appcontext/

Related

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: student.email

I have a registration form and am trying to add student data to the database model(Student) but i get this error upon submiting the form data
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: student.email
[SQL: INSERT INTO student (username, email, image_file, password) VALUES (?, ?, ?, ?)]
[parameters: ('elijah', 'elijah#gmail.com', 'default.jpg', '$2b$12$lo4MLsE/hdI6SOnUr3lg5eg02u.u5xfRJYwKQzMn3bohXglif/73S')]
(Background on this error at: https://sqlalche.me/e/14/gkpj)
Am not sure of what's causing the error, have tried dropping and recreating my database modles again but the error persists.
This is my student model where the error is pointing to student.email
from datetime import datetime
from ..utils.db import db
class Student(db.Model):
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(255), nullable=True, default='default.jpg')
password = db.Column(db.String(120), nullable=False)
student_mark = db.relationship('Mark', backref='mark')
student_qn = db.relationship('StudentQuestion',backref='examinee')
def __repr__(self):
return f"Student('{self.username}', '{self.email}')"
def save(self):
db.session.add(self)
db.session.commit()
and this is the route that has the submission form which throws the error after i insert data into the form
from flask import render_template, url_for, flash, redirect, Blueprint
from .registerform import RegistrationForm
from flask_bcrypt import Bcrypt
from ..models.models import Student
from ..utils.db import db
bcrypt = Bcrypt()
register_route = Blueprint('register_route', __name__)
#register_route.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
student= Student(username=form.username.data, email=form.email.data, password=hashed_password)
db.session.add(student)
db.session.commit()
flash(f'Welcome {form.username.data} ,your can now login!')
return redirect(url_for('login_route.login'))
return render_template('register.html', title='RegisterPage', form=form)
What could be the problem and how can i avoid it!

Why i am getting UnboundLocalError in Flask?

this is my app.py code but i am receiving unbound local error after adding another path for delete and creating the function delete.
from crypt import methods
from email.policy import default
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Todo(db.Model):
sno = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
desc = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self) -> str:
return f"{self.sno} - {self.title}"
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
title = request.form["title"]
desc = request.form["desc"]
todo = Todo(title=title, desc=desc)
db.session.add(todo)
db.session.commit()
mytodo = Todo.query.all()
return render_template('index.html', mytodo=mytodo)
#app.route('/delete/<int:sno>')
def delete(sno):
todo = Todo.query.filter_by(sno==sno).first()
db.session.delete(todo)
db.session.commit()
return redirect('/')
if __name__ == "__main__":
app.run(debug=True, port=8000)
Below i've added the screenshot of the errors i am getting even when i just visit the root url.
Problem
If the server receive a GET /, then you won't define te title variable, but would try to use it at Todo(title=title, desc=desc) so an error
Fix
All the creation code should be in the if POST branch
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
title = request.form["title"]
desc = request.form["desc"]
todo = Todo(title=title, desc=desc)
db.session.add(todo)
db.session.commit()
mytodo = Todo.query.all()
return render_template('index.html', mytodo=mytodo)

Why is my Flask code not uploading data to my SQLite Database?

I have this code designed to login users with passwords using Flask. It is somehow always running the exception in the trycatch. Can someone tell me where is the problem?
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String(200), nullable=False);
password = db.Column(db.String(20), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.datetime.utcnow)
def __repr__(self):
return '<User %r' % self.id
#app.route('/', methods=['POST','GET'])
def index():
if request.method == 'POST':
user_content = request.form['user']
password_content = request.form['password']
new_user = User(user=user_content)
new_password = User(password=password_content)
try:
db.session.add(new_user)
db.session.add(new_password)
db.session.commit()
return redirect('/')
except:
return ""
else:
users = User.query.order_by(User.date_created).all()
return render_template('index.html', users=users)
if __name__ == "__main__":
app.run(debug=True)

Flask-SQLAlchemy sqlite crashing on db.session.commit()

I have the following code. I'm trying to insert user data into a sqlite database using SQLAlchemy it crashes when I give the following command in the python prompt. I'm trying to add the users to the database then once I commit I want to query the database and display the information to verify it got inserted into the database. For now I have it only displaying to the prompt I haven't developed any methods to render it.
from DIRT import db
db.create_all()
from DIRT import User, Post
user_1 = User(username="John Wick", email="jw#gmail.com", password="password")
user_2 = User(username="John Snow", email="js#gmail.com", password="password")
db.session.add(user_1)
db.session.add(user_2)
db.session.commit()
Below is my code for the DIRT.py
from datetime import datetime
from flask import Flask, render_template, url_for, flash, redirect
from flask_sqlalchemy import SQLAlchemy
from MyForms import RegisterForm, LoginForm
app = Flask(__name__)
# creating secret numbers to prevent modified cookie attack, or cross-site attacks
app.config['SECRET_KEY'] = '4b15463cce52d7b99874c9fb2312d580'
# database uri
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///dirt.db'
# database
db = SQLAlchemy(app)
# user model for the sql database
# class User(db.Model):
# id = db.Column(db.Integer, primary_key=True)
# username = db.Column(db.String(25), unique=True, nullable=False)
# email = db.Column(db.String(50), unique=True, nullable=False)
# image_file = db.Column(db.String(25), nullable=False, default='default.jpg')
# password = db.Column(db.String(50), nullable=False)
# posts = db.relationship('Post', backref='author', lazy=True)
# def __repf__(self):
# return f"User('{self.username}', '{self.email}', '{self.image_file}')"
class User(db.Model):
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)
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}')"
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)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
posts = [
{
'author': 'Cloud Strife',
'title': 'Where do we find Aeris..',
'content': 'So we are trying to find her',
'date_posted': 'November 12, 2019'
},
{
'author': 'Cecil Paladin',
'title': 'Where is the crystal sword',
'content': 'Trying to find the crystal bridge',
'date_posted': 'July 10, 2019'
}
]
#app.route("/")
#app.route("/home")
def home():
return render_template('home.html', posts=posts)
#app.route("/about")
def about():
return render_template('about.html', title='About')
#app.route("/register", methods=['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
flash(f'Account created for {form.username.data} successfully!', 'success')
return redirect(url_for('home'))
return render_template('register.html', title='Register', form=form)
# #app.route("/login", methods=['GET', 'POST'])
# def login():
# MyForm = LoginForm()
# return render_template('login.html', title='Login', form=MyForm)
#app.route("/login", methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
if form.email.data == 'onyxbird#hotmail.com' and form.password.data == 'sandman23':
flash(f'{form.email.data} has logged in!', 'success')
return redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check email and password', 'danger')
return render_template('login.html', title='Login', form=form)
if __name__ == '__main__':
# app.run(host='0.0.0.0', port='8080')
# above is production mode
app.run(debug=True)
This is the errors I'm getting:
*db.session.commit()
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Users\onyxb\PycharmProjects\DIRT\venv\lib\site-packages\sqlalchemy\orm\scoping.py", line 162, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "C:\Users\onyxb\PycharmProjects\DIRT\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1027, in commit
self.transaction.commit()
File "C:\Users\onyxb\PycharmProjects\DIRT\venv\lib\site-packages\sqlalchemy\orm\session.py", line 492, in commit
self._assert_active(prepared_ok=True)
File "C:\Users\onyxb\PycharmProjects\DIRT\venv\lib\site-packages\sqlalchemy\orm\session.py", line 288, in _assert_active
raise sa_exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlite3.IntegrityError) NOT NULL constraint failed: user.image_file
[SQL: INSERT INTO user (username, email, password) VALUES (?, ?, ?)]
[parameters: ('John Wick', 'jw#gmail.com', 'password')]
(Background on this error at: http://sqlalche.me/e/gkpj) (Background on this error at: http://sqlalche.me/e/7s2a)*

DataError: (psycopg2.DataError) invalid input syntax for integer

I'm trying to add Flask-Login to my Flask-Python app but I'm having this error and I don't know why.
I guess thats my user.loader that isnt correct but the idea is to load the user based on the ID or email.
Any idea what am I doing wrong?
Thanks in advance
Regards
full error :
DataError: (psycopg2.DataError) invalid input syntax for integer:
"t#t.pt" LINE 3: WHERE users.uid = 't#t.pt'
app.py
from flask import Flask, render_template, request, session, redirect, url_for
from models import db, User
from forms import SignupForm, LoginForm
from flask_login import LoginManager, UserMixin, \
login_required, login_user, logout_user
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/polex'
db.init_app(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
app.secret_key = "development-key"
#login_manager.user_loader
def user_loader(uid):
"""Given *user_id*, return the associated User object.
:param unicode user_id: user_id (email) user to retrieve
"""
return User.query.get(uid)
#app.route("/")
def index():
return render_template("index.html")
#app.route("/about")
def about():
return render_template("about.html")
#app.route("/signup", methods=["GET", "POST"])
def signup():
if 'email' in session:
return redirect(url_for('home'))
form = SignupForm()
if request.method == "POST":
if form.validate() == False:
return render_template('signup.html', form=form)
else:
newuser = User(form.first_name.data, form.last_name.data, form.email.data, form.password.data)
db.session.add(newuser)
db.session.commit()
session['email'] = newuser.email
return redirect(url_for('home'))
elif request.method == "GET":
return render_template('signup.html', form=form)
#app.route("/login", methods=["GET", "POST"])
def login():
print db
form = LoginForm()
if request.method == "POST":
if form.validate() == False:
return render_template("login.html", form=form)
else:
email = form.email.data
password = form.password.data
user = User.query.filter_by(email=email).first()
if user is not None and user.check_password(password):
login_user(user, remember=True)
return redirect(url_for('home'))
else:
return redirect(url_for('login'))
elif request.method == 'GET':
return render_template('login.html', form=form)
#app.route("/logout")
def logout():
session.pop('email', None)
return redirect(url_for('index'))
#app.route("/home", methods=["GET", "POST"])
def home():
return render_template("home.html")
if __name__ == "__main__":
app.run(debug=True)
models.py
from flask_sqlalchemy import SQLAlchemy
from werkzeug import generate_password_hash, check_password_hash
from flask_login import UserMixin
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
uid = db.Column(db.Integer, primary_key = True)
firstname = db.Column(db.String(100))
lastname = db.Column(db.String(100))
email = db.Column(db.String(120), unique=True)
pwdhash = db.Column(db.String(54))
#-----login requirements-----
def is_active(self):
#all users are active
return True
def get_id(self):
# returns the user e-mail. not sure who calls this
return self.email
def is_authenticated(self):
return self.authenticated
def is_anonymous(self):
# False as we do not support annonymity
return False
def __init__(self, firstname, lastname, email, password):
self.firstname = firstname.title()
self.lastname = lastname.title()
self.email = email.lower()
self.set_password(password)
def set_password(self, password):
self.pwdhash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.pwdhash, password)
You're using User.query.get(uid) where you need to use filter or filter_by:
#login_manager.user_loader
def user_loader(user_email):
"""Given *user_id*, return the associated User object.
:param unicode user_id: user_id (email) user to retrieve
"""
return User.query.filter_by(email=user_email).first()
get() takes a Primary Key (which would be user id in this case) and returns it, filter is what you need here if you're trying to limit on a column value.

Categories

Resources