Related
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)
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/
I have started work on a project and have decided before I get too deep to get my ORM sorted out (this means going back over and re writing my classes). I believe my code is correct but I am getting a 'TypeError' whenever I try to create the database schema using Python. I load up the Python console whilst in my project directory, and type 'from app import db' which works fine. After the command 'db.create_all()' (which worked using a basic example) I am thrown the error:
'File
"C:\Users\owner\AppData\Local\Programs\Python\Python38-32\lib\site-packages\sqlalchemy\dialects\mysql\base.py",
line 2016, in visit_VARCHAR
return self._extend_string(type_, {}, "VARCHAR(%d)" % type_.length) TypeError: %d format: a number is required, not type'
I am given no clue as to where in my actual code the cause could be, and am at a total loss.
Any help would be great - a lot of code is commented out and some other code left in for now as I'm in the process of adding my ORM but it was implemented without SQLAlchemy initially. Below is my code for 'init.py':
from flask import Flask, render_template, url_for, flash, redirect, g, request, session, send_from_directory, send_file
from heychef.config import Config
from flask_sqlalchemy import SQLAlchemy
import os
import bcrypt
import uuid
import json
import ssl
from datetime import datetime
from datetime import timedelta
from heychef.models.Agency import Agency
from heychef.models.User import User
from heychef.models.Shift import Shift
from flaskext.mysql import MySQL
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
from heychef.models.Agent import Agent
#app.before_request
def before_request():
g.agent = None
g.agency = None
if 'agent' in session:
g.agent = session['agent']
if 'agency' in session:
g.agency = session['agency']
##########################################################
############# Agent Routes ################
##########################################################
#app.route("/")
def home():
return render_template('agent-views/signup.html'), 200
#app.route("/agent-signup", methods = ['POST', 'GET'])
def agentSignup():
if request.method == 'POST':
email = request.form['inputEmail']
firstName = request.form['inputFirstName']
secondName = request.form['inputSecondName']
password = request.form['inputPassword']
rPassword = request.form['inputConfirmPassword']
if(password != rPassword):
flash('Passwords do not match.', 'danger')
return render_template('agent-views/signup.html')
else:
hashedPwd = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
agent = Agent(firstName, secondName, email, hashedPwd)
agent.addAgent(self)
flash('Account created, you can log in now.', 'success')
return render_template('agent-views/signup.html')
#app.route("/agent-login", methods = ['POST','GET'])
def agentLogin():
if request.method == 'POST':
session.pop('agent', None)
email = request.form['inputEmail']
pwd = request.form['inputPassword']
connection = mysql.get_db()
cursor = connection.cursor()
result, msg = Agent.agentLogin(connection, cursor, email, pwd)
if(result):
session['agent'] = email
flash(msg, 'success')
return redirect(url_for('agentDashboard'))
else:
flash(msg, 'danger')
return render_template('agent-views/login.html')
else:
return render_template('agent-views/login.html')
#app.route("/agent-dashboard", methods = ['GET'])
def agentDashboard():
if g.agent:
return render_template('agent-views/dashboard.html'), 200
else:
msg = "Please log in"
flash(msg, 'warning')
return redirect(url_for('agentLogin'))
if __name__ == "__main__":
app.run()
and here is my Agent Class:
from heychef.models.User import User
#from heychef.models.data.AgentDb import AgentDb
from heychef import db
class Agent(db.Model):
agentId = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
firstName = db.Column(db.String(80), unique=False, nullable=False, primary_key=False)
secondName = db.Column(db.String(80), unique=False, nullable=False, primary_key=False)
email = db.Column(db.String(80), unique=False, nullable=False, primary_key=False)
level = db.Column(db.String(80), unique=False, nullable=True, primary_key=False)
agencyId = db.Column(db.Integer, unique=False, nullable=True, primary_key=False)
addressLine1 = db.Column(db.String(80), unique=False, nullable=True, primary_key=False)
addressLine2 = db.Column(db.String(80), unique=False, nullable=True, primary_key=False)
addressLine3 = db.Column(db.String(80), unique=False, nullable=True, primary_key=False)
postcode = db.Column(db.String(20), unique=False, nullable=True, primary_key=False)
passwordHash = db.Column(db.String(256), unique=False, nullable=False, primary_key=False)
def __repr__(self):
return "<Agent(firstName='%s', lastName='%s')>" % (self.firstName, self.lastName)
def __init__(self, firstName, secondName, email, hashedPwd):
self.agentId = 1001
self.firstName = firstName
self.secondName = secondName
self.email = email
self.passwordHash = hashedPwd
#staticmethod
def agentEmailExists(cursor, email):
exists = AgentDb.agentEmailExistsDb(cursor, email)
return exists
#staticmethod
def addAgent(agent):
db.session.add(self)
db.session.commit()
#staticmethod
def agentLogin(connection, cursor, email, pwd):
failMsg = 'Email or Password does not match.'
successMsg = 'Successfully logged in.'
result = AgentDb.agentLoginDb(connection, cursor, email, pwd)
if(result):
msg = successMsg
else:
msg = failMsg
return result, msg
#staticmethod
def getWork(cursor):
work = AgentDb.getWorkDb(cursor)
return work
any help would be ace as I'm really struggling!
Many thanks
The error seems to be related to a VARCHAR (String)db column and points out that it has received a Non-Integer value ,so there might be a db.string() model field with a Non-Integer or empty parenthesis in the other model Classes in your project.
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)*
I was finishing up a simple little user login with Flask and Bcrypt. However, when trying to login with a user that is stored in my database, I keep encountering a runtime error. It looks like some sort of loop that's breaking. Being that I'm pretty new to programming, this has been incredibly challenging to figure out what I'm doing wrong. Hopefully someone here can help out! I'll past the relevant code below:
Here's the issue I'm getting. It just keeps looping this until it exceeds the maximum:
File "C:\Users\desktop\test\app\models.py", line 37, in password
return self.password
File "C:\Users\.virtualenvs\flask\lib\site-packages\sqlalchemy\ext\hybrid.py",
line 742, in get
return self.fget(instance)
File "C:\Users\desktop\test\app\models.py", line 37, in password
Models.py
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
nickname = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password = db.Column(db.String(100))
posts = db.relationship('Post', backref='author', lazy='dynamic',
primaryjoin="User.id==Post.user_id")
about_me = db.Column(db.String(140))
last_seen = db.Column(db.DateTime)
followed = db.relationship('User',
secondary=followers,
primaryjoin=(followers.c.follower_id == id),
secondaryjoin=(followers.c.followed_id == id),
backref=db.backref('followers', lazy='dynamic'),
lazy='dynamic')
#hybrid_property
def password(self):
return self.password
#password.setter
def set_password(self, plaintext):
self.password = bcrypt.generate_password_hash(plaintext)
def is_correct_password(self, plaintext):
return bcrypt.check_password_hash(self.password, plaintext)
Forms.py
class LoginForm(Form):
nickname = TextField('Nickname', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
Views.py Login
#app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(nickname=form.nickname.data).first_or_404()
if user.is_correct_password(form.password.data):
login_user(user)
flash("you've been logged in!, 'success'")
return redirect(url_for('index'))
else:
flash('your email or password doesnt match!', 'error')
return redirect(url_for('login'))
return render_template('login.html',
title='Sign In',
form=form)
Views.py Registration
#app.route('/register', methods=('GET', 'POST'))
def register():
form = forms.RegisterForm()
if form.validate_on_submit():
user = User(nickname=form.nickname.data, emai=form.email.data, password=form.password.data)
db.session.add(user)
db.session.commit()
flash('User successfully registered')
return redirect(url_for('login'))
return render_template('register.html', form=form)
You should use different names for column and property
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
password_hash = db.Column(db.String(100))
#hybrid_property
def password(self):
return self.password_hash
#password.setter
def set_password(self, plaintext):
self.password_hash = bcrypt.generate_password_hash(plaintext)