'sqlalchemy.exc.NoForeignKeysError in flask and sqlalchemy.exc.OperationalError

Me and my friends are working on a flask project and we are facing the following errors while implementing the database. The error occurs when we submit the sign up form

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: employee [SQL: SELECT employee.id AS employee_id, employee.username AS employee_username, employee.email AS employee_email, employee.password AS employee_password, employee."firstName" AS "employee_firstName", employee."lastName" AS "employee_lastName", employee."phoneNum" AS "employee_phoneNum", employee."SSN" AS "employee_SSN", employee.role AS employee_role, employee.insurance AS employee_insurance, employee.salary AS employee_salary, employee.dob AS employee_dob, employee.gender AS employee_gender, employee."houseNum" AS "employee_houseNum", employee.streat AS employee_streat, employee.province AS employee_province, employee.city AS employee_city, employee."postalCode" AS "employee_postalCode", employee."worksInBranch" AS "employee_worksInBranch" FROM employee WHERE employee.email = ? LIMIT ? OFFSET ?] [parameters: ('[email protected]', 1, 0)] (Background on this error at: https://sqlalche.me/e/14/e3q8)

The code is as follows:

class Patient(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True)
    email = db.Column(db.String(30), nullable=False, unique=True)
    password = db.Column(db.String(30), nullable=False)
    firstName = db.Column(db.String(30), nullable=False)
    lastName = db.Column(db.String(30), nullable=False)
    phoneNum = db.Column(db.Integer, nullable=False)
    SSN = db.Column(db.Integer, nullable=False)
    insurance = db.Column(db.String(50))
    dob = db.Column(db.Date, nullable=False)
    gender = db.Column(db.String(10), nullable=False)
    houseNum = db.Column(db.String(30), nullable=False)
    street = db.Column(db.String(30), nullable=False)
    province = db.Column(db.String(30), nullable=False)
    city = db.Column(db.String(30), nullable=False)
    postalCode = db.Column(db.String(30), nullable=False)
    appointments = db.relationship(
        "Appointment", backref="patient"
    )  # Makes accessing all patients appointments easier. Referncing class in relationship, we use uppper case names of classes
    payments = db.relationship("Payment", backref="patient")
    review = db.relationship(
        "Review", backref="patient", uselist=False
    )  # uselist=False declares one to one relationship
    record = db.relationship(
        "Record", backref="patient", uselist=False
    )  # uselist=False declares one to one relationship


class Employee(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True)
    email = db.Column(db.String(30), nullable=False, unique=True)
    password = db.Column(db.String(30), nullable=False)
    firstName = db.Column(db.String(30), nullable=False)
    lastName = db.Column(db.String(30), nullable=False)
    phoneNum = db.Column(db.Integer, nullable=False)
    SSN = db.Column(db.Integer, nullable=False)
    role = db.Column(db.String(30), nullable=False)
    insurance = db.Column(db.String(50))
    salary = db.Column(db.Numeric(2), default=0.00)
    dob = db.Column(db.Date, nullable=False)
    # signUpDate = db.Column(db.Date, default=func.now())   Automaticall creates dates of for us
    gender = db.Column(db.String(10), nullable=False)
    houseNum = db.Column(db.String(30), nullable=False)
    streat = db.Column(db.String(30), nullable=False)
    province = db.Column(db.String(30), nullable=False)
    city = db.Column(db.String(30), nullable=False)
    postalCode = db.Column(db.String(30), nullable=False)
    # managesBranch = db.Column(db.Integer, db.ForeignKey('branch.branchId')) #$$$ one to one. Can be null, IDK CHECK IF CAUSES ERROR
    # managesBranch = db.relationship('Branch', backref='employee', uselist=False)
    worksInBranch = db.Column(
        db.Integer, db.ForeignKey("branch.branchId"), nullable=False
    )
from curses.ascii import EM
from email import message
from Website import views
from . import db
from flask import (
    Blueprint,
    render_template,
    request,
    flash,
    redirect,
    url_for,
    redirect,
)

from .models import Patient, Employee

from Website import models
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import login_user, login_required, logout_user

auth = Blueprint("auth", __name__)


@auth.route("/signup", methods=["GET", "POST"])
def signup():
    message = None
    data = request.form
    print(data)
    # return render_template("login.html", boolean=True)
    if request.method == "POST":
        username = request.form.get("username")
        email = request.form.get("email")
        password1 = request.form.get("password1")
        password2 = request.form.get("password2")
        firstName = request.form.get("firstName")
        lastName = request.form.get("lastName")
        phoneNum = request.form.get("phoneNum")
        SSN = request.form.get("SSN")
        insurance = request.form.get("insurance")
        salary = request.form.get("salary")
        role = request.form.get("role")
        gender = request.form.get("gender")
        dob = request.form.get("dob")
        houseNum = request.form.get("houseNum")
        streat = request.form.get("streat")
        province = request.form.get("province")
        city = request.form.get("city")

        postCode = request.form.get("postalCode")

        if role == Patient:
            user = Patient.query.filter_by(email=email).first()
        else:
            user = Employee.query.filter_by(email=email).first()

        if user:
            message = "Email already exists"

        elif len(username) <= 2:
            # flash('username must be greater than 1 characters', category='error')
            # return redirect(request.url)
            message = "Username must be greater than 1 characters"
        elif len(firstName) < 3 and not (firstName.isalpha()):
            # flash('First Name must be greater than 3 characters and only includes characters', category='error')
            # return redirect(request.url)
            message = "First Name must be greater than 3 characters and only includes characters"
        elif len(lastName) < 3 and not (lastName.isalpha()):
            # flash('Last Name must be greater than 3 characters and only includes characters', category='error')
            # return redirect(request.url)
            message = "Last Name must be greater than 3 characters and only includes characters"
        elif (len(email) < 2) and not ("@" in email):
            # flash('Email must be greater than 2 characters and includes @', category='error')
            # return redirect(request.url)
            message = "Email must be greater than 2 characters and includes @"
        elif password1 != password2:
            # flash('passwords must match', category='error')
            # return redirect(request.url)
            message = "Passwords must match"
        elif len(phoneNum) < 2 or not (phoneNum.isnumeric()):
            # flash('Phone number must be greater than 2 numbers and only includes numbers', category='error')
            # return redirect(request.url)
            message = (
                "Phone number must be greater than 2 numbers and only includes numbers"
            )
        elif len(SSN) < 2 or not (SSN.isnumeric()):
            # flash('SSN must be greater than 2 numbers and only includes numbers', category='error')
            # return redirect(request.url)
            message = "SSN must be greater than 2 numbers and only includes numbers"
        elif len(insurance) < 2 or not (insurance.isalnum()):
            # flash('Insurance name must be greater than 2 characters and includes numbers or characters', category='error')
            # return redirect(request.url)
            message = "Insurance name must be greater than 2 characters and includes numbers or characters"
        elif len(salary) < 1 or not (salary.isnumeric()):
            # flash('Salary must be greater than 1 number and only includes numbers', category='error')
            # return redirect(request.url)
            message = "Salary must be greater than 1 number and only includes numbers"
        elif len(houseNum) < 2 or not (houseNum.isalnum()):
            # flash('House number name must be greater than 2 characters and includes numbers or characters', category='error')
            # return redirect(request.url)
            message = "House number name must be greater than 2 characters and includes numbers or characters"
        elif len(streat) < 2 or not (streat.isalnum()):
            # flash('Streat must be greater than 2 characters and includes numbers or characters', category='error')
            # return redirect(request.url)
            message = "Streat must be greater than 2 characters and includes numbers or characters"
        elif len(city) < 2 or not (city.isalpha()):
            # flash('City name must be greater than 2 characters and includes only characters', category='error')
            # return redirect(request.url)
            message = "City name must be greater than 2 characters and includes only characters"
        elif len(province) < 2 or not (province.isalpha()):
            # flash('Province name must be greater than 2 characters and includes only characters', category='error')
            # return redirect(request.url)
            message = "Province name must be greater than 2 characters and includes only characters"
        elif len(postCode) < 2 or not (postCode.isalnum()):
            # flash('Postal code must be greater than 2 characters and includes only characters and numbers', category='error')
            # return redirect(request.url)
            message = "Postal code  name must be greater than 2 characters and includes only characters and numbers"
        else:
            # flash("Account Created Successfully", category='success')
            # return redirect(request.url)
            # add user to database
            if role == "Patient":
                new_user = Patient(
                    username=username,
                    email=email,
                    firstName=firstName,
                    lastName=lastName,
                    password=generate_password_hash(password1, method="sha256"),
                    phoneNum=phoneNum,
                    gender=gender,
                    SSN=SSN,
                    insurance=insurance,
                    dob=dob,
                    houseNum=houseNum,
                    streat=streat,
                    city=city,
                    province=province,
                    postCode=postCode,
                )
                db.session.add(new_user)
                db.session.commit()
                message = "Account Created Successfully"
                return redirect(url_for("views.home"))
            else:
                new_user = Employee(
                    username=username,
                    email=email,
                    firstName=firstName,
                    lastName=lastName,
                    password=generate_password_hash(password1, method="sha256"),
                    phoneNum=phoneNum,
                    gender=gender,
                    dob=dob,
                    SSN=SSN,
                    insurance=insurance,
                    houseNum=houseNum,
                    streat=streat,
                    city=city,
                    province=province,
                    postCode=postCode,
                )
                db.session.add(new_user)
                db.session.commit()
                message = "Account Created Successfully"
                return redirect(url_for("views.home"))

    return render_template("signup.html", error=message)

#DROP DATABASE IF EXISTS CSI2132project;
CREATE DATABASE CSI2132project;

drop table if exists Patient cascade;
drop table if exists Appointment cascade;
drop table if exists Payment cascade;
drop table if exists Review cascade;
drop table if exists `User` cascade;
drop table if exists `Comment` cascade;
drop table if exists Employee cascade;
drop table if exists Tooth cascade;
drop table if exists ProgressNote cascade;
drop table if exists Treatment cascade;
drop table if exists Fee_Charge cascade;
drop table if exists Branch cascade;
drop table if exists Records cascade;
drop table if exists Appointment_Procedure cascade;
drop table if exists Invoice cascade;


CREATE TABLE Patient(
    Patient_ID int(9) PRIMARY KEY,
    Email VARCHAR(30) NOT NULL,
    `Password` VARCHAR(30) NOT NULL,
    First_name VARCHAR(30) NOT NULL,
    Last_name VARCHAR(30) NOT NULL,
    Phone_num int(10) NOT NULL,
    SSN int(9) NOT NULL,
    Insurance VARCHAR(30) NOT NULL,
    Date_of_birth TIMESTAMP NOT NULL,
    Gender VARCHAR(20) NOT NULL,
    Street_num int NOT NULL,
    Street_name VARCHAR(100) NOT NULL,
    Postal_code VARCHAR(30) NOT NULL,
    City VARCHAR(30) NOT NULL,
    Province VARCHAR(30) NOT NULL
    );
CREATE TABLE Employee(
    Employee_ID int(9) PRIMARY KEY,
    Email VARCHAR(30) NOT NULL,
    `Password` VARCHAR(30) NOT NULL,
    First_name VARCHAR(30) NOT NULL,
    Last_name VARCHAR(30) NOT NULL,
    Phone_num int(10) NOT NULL,
    SSN int(9) NOT NULL,
    Employee_role VARCHAR(50) NOT NULL,
    Insurance VARCHAR(50) NOT NULL,
    Salary decimal(10,2) NOT NULL DEFAULT '0.00',
    Date_of_birth TIMESTAMP NOT NULL,
    Gender VARCHAR(20) NOT NULL,
    Street_num int NOT NULL,
    Street_name VARCHAR(100) NOT NULL,
    Province VARCHAR(100) NOT NULL,
    City VARCHAR(100) NOT NULL,
    Postal_code VARCHAR(20) NOT NULL,
    Branch_manager VARCHAR(20) NOT NULL,
    FOREIGN KEY(Branch_manager) REFERENCES Branch(Branch_manager)
    
);

The Github link to the repo is: https://github.com/ritvik130/CSI2132_Project/tree/main if more info is required.

Thank you for the help!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source