在Flask网站中使用SQLAlchemy操作数据库时遇到的问题。

huangapple go评论72阅读模式
英文:

Problems while operating with a database in SQLAlchemy in a Flask website

问题

I see you're facing an issue with your Flask application after adding the "is_employer" column to the "user" table. The error message you provided indicates that there is no such column in the "user" table when you try to access it.

Here are a few steps to troubleshoot this issue:

  1. Database Migration: Ensure that you have applied the database migration to update the table schema. It appears that you added the "is_employer" column manually, but you should use a migration tool like Flask-Migrate to make these changes safely. Double-check that the migration was applied successfully.

  2. SQLAlchemy Model: Confirm that your SQLAlchemy model matches the updated table schema. The model definition should include the "is_employer" column, and it should match the database schema.

  3. HTML Form: Check the HTML form for the registration page. It seems that you've added the "is_employer" field to the form correctly. Make sure there are no typos or errors in the form field names.

  4. Database File: Verify that you are using the correct database file (database.db) and that it is located in the expected directory. Sometimes, issues can occur if you're connecting to the wrong database file.

  5. Data Types: Ensure that the data types in your SQLAlchemy model match those in your database schema. The "is_employer" column is a Boolean, so make sure it's defined as such in both places.

  6. Migration Order: Confirm that the migration to add the "is_employer" column was executed before any code that tries to access it. The error suggests that the column is missing, so ensure that the migration is applied before any database queries or operations.

  7. Database Connection: Double-check the database connection URI in your Flask app configuration. It should point to the correct database file (database.db).

  8. SQLAlchemy Session: If you've made changes to your database schema, make sure you've restarted your Flask application to apply those changes. SQLAlchemy might cache schema information.

By carefully reviewing these points and ensuring consistency between your database schema, SQLAlchemy model, and HTML form, you should be able to resolve the issue with your Flask application.

英文:

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

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

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: (&#39;wdawdawd&#39;, 1, 0)]
(Background on this error at: https://sqlalche.me/e/20/e3q8)

<!-- end snippet -->

And this is the flask application code

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

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[&#39;SQLALCHEMY_DATABASE_URI&#39;] = &#39;sqlite:///database.db&#39;
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
app.config[&#39;SECRET_KEY&#39;] = &#39;thisisasecretkey&#39;


login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = &#39;login&#39;


@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={&quot;placeholder&quot;: &quot;Username&quot;})

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

    submit = SubmitField(&#39;Register&#39;)

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


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

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

    submit = SubmitField(&#39;Login&#39;)


@app.route(&#39;/&#39;)
def home():
    return render_template(&#39;index.html&#39;)


@app.route(&#39;/login&#39;, methods=[&#39;GET&#39;, &#39;POST&#39;])
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(&#39;dashboard&#39;))
    return render_template(&#39;login.html&#39;, form=form)


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


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


@ app.route(&#39;/register&#39;, methods=[&#39;GET&#39;, &#39;POST&#39;])
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(&#39;login&#39;))

    return render_template(&#39;register.html&#39;, form=form)


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

<!-- end snippet -->

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

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

import sqlite3

connection = sqlite3.connect(&#39;database.db&#39;)

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

<!-- end snippet -->

And here is the html code for the register form

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

    &lt;div class=&quot;register-box&quot;&gt;
        &lt;h1&gt;Register to Clean Connect&lt;/h1&gt; &lt;br&gt;
        &lt;form method=&quot;POST&quot; action=&quot;&quot;&gt;
            {{ form.hidden_tag() }} 

            {{ form.username(placeholder=&#39;&#39;, id=&#39;username-input&#39;) }} 
            &lt;label id=&quot;username-label&quot;&gt;Username&lt;/label&gt;
            &lt;br&gt;&lt;br&gt;
            
            {{ form.password(placeholder=&#39;&#39;, id=&#39;password-input&#39;) }} 
            &lt;label id=&quot;password-label&quot;&gt;Password&lt;/label&gt;
            &lt;br&gt;&lt;br&gt;
            
            &lt;label id=&quot;is_employer-label&quot;&gt;Are you an employer?&lt;/label&gt;
            {{ form.is_employer(id=&#39;is_employer-input&#39;) }} 

            {{ form.submit(id=&#39;submit-button&#39;) }} &lt;br&gt;&lt;br&gt;
        &lt;/form&gt;
        &lt;a href=&quot;{{url_for(&#39;login&#39;)}}&quot;&gt;Already have an account? Log in&lt;/a&gt;
    &lt;/div&gt;

<!-- end snippet -->

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

答案1

得分: 1

我成功解决了问题,多亏了一个名叫python_user的人。我使用了数据库的绝对路径,现在一切都正常。

英文:

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.

huangapple
  • 本文由 发表于 2023年5月22日 00:18:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76300843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定