Title: Problems while operating with a database in SQLAlchemy in a Flask website
Tags: python,database,flask,flask-sqlalchemy

Question: I had a fully working flask application with a register and login forms that were linked to the database. Next I decided to add one more column to the table named user in the database and I named it is_employer. After that I updated the database to have the table user and have all the new columns. I also modified the python and html code to work with the change. But after the change all I get is a problem while trying to register or login


sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: user.is_employer
[SQL: SELECT user.id AS user_id, user.username AS user_username, user.password AS user_password, user.is_employer AS user_is_employer 
FROM user 
WHERE user.username = ?
 LIMIT ? OFFSET ?]
[parameters: ('wdawdawd', 1, 0)]
(Background on this error at: https://sqlalche.me/e/20/e3q8)



And this is the flask application code


from flask import Flask, render_template, url_for, redirect
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin, login_user, LoginManager, login_required, logout_user, current_user
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import InputRequired, Length, ValidationError
from flask_bcrypt import Bcrypt

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
app.config['SECRET_KEY'] = 'thisisasecretkey'


login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'


@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), nullable=False, unique=True)
    password = db.Column(db.String(80), nullable=False)
    is_employer = db.Column(db.Boolean, default=False)


class RegisterForm(FlaskForm):
    username = StringField(validators=[
                           InputRequired(), Length(min=4, max=20)], render_kw={"placeholder": "Username"})

    password = PasswordField(validators=[
                             InputRequired(), Length(min=8, max=20)], render_kw={"placeholder": "Password"})
    
    is_employer = BooleanField()

    submit = SubmitField('Register')

    def validate_username(self, username):
        existing_user_username = User.query.filter_by(
            username=username.data).first()
        if existing_user_username:
            raise ValidationError(
                'That username already exists. Please choose a different one.')


class LoginForm(FlaskForm):
    username = StringField(validators=[
                           InputRequired(), Length(min=4, max=20)], render_kw={"placeholder": "Username"})

    password = PasswordField(validators=[
                             InputRequired(), Length(min=8, max=20)], render_kw={"placeholder": "Password"})

    submit = SubmitField('Login')


@app.route('/')
def home():
    return render_template('index.html')


@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.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('dashboard'))
    return render_template('login.html', form=form)


@app.route('/dashboard', methods=['GET', 'POST'])
def dashboard():
    if current_user.is_authenticated:
        return render_template('dashboard.html', gracz=current_user.username)
    else: 
        return redirect(url_for('login'))


@app.route('/logout', methods=['GET', 'POST'])
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))


@ app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegisterForm()

    if form.validate_on_submit():
        hashed_password = bcrypt.generate_password_hash(form.password.data)
        new_user = User(username=form.username.data, password=hashed_password, is_employer=form.is_employer.data)
        db.session.add(new_user)
        db.session.commit()
        return redirect(url_for('login'))

    return render_template('register.html', form=form)


if __name__ == "__main__":
    print(dir(db.Model))
    app.run(debug=True)



It connects to the .db file named database.db which has the table named user with columns id, username, password, and is_employer. This is the code I used for creation of the table


import sqlite3

connection = sqlite3.connect('database.db')

with connection:
    connection.execute(
        "CREATE TABLE user (id INTEGER PRIMARY KEY, username TEXT, password TEXT, is_employer BOOLEAN)"
    )



And here is the html code for the register form


    <div class="register-box">
        <h1>Register to Clean Connect</h1> <br>
        <form method="POST" action="">
            {{ form.hidden_tag() }} 

            {{ form.username(placeholder='', id='username-input') }} 
            <label id="username-label">Username</label>
            <br><br>
            
            {{ form.password(placeholder='', id='password-input') }} 
            <label id="password-label">Password</label>
            <br><br>
            
            <label id="is_employer-label">Are you an employer?</label>
            {{ form.is_employer(id='is_employer-input') }} 

            {{ form.submit(id='submit-button') }} <br><br>
        </form>
        <a href="{{url_for('login')}}">Already have an account? Log in</a>
    </div>



I tried finding the problem for quite a while and I would appreciate help.

Answer: I managed to solve the problem thanks to a person named python_user. I used the absolute path to the database and everything works fine now.