You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask登录表单SQLAlchemy报错:如何绑定列与数据表?

Flask登录功能开发:数据表创建问题

我正在用Flask搭建带登录功能的网页,目前开发到登录表单环节,Flask代码和HTML页面代码如下,运行时出现no such table: users错误,想知道怎么把定义的模型和数据表绑定。知道db.create_all()可以创建表,但教程说不用db.Table,有点困惑,求解决。

Flask代码

from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.app_context().push()
app.secret_key = 'hello'
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///users.sqlite3'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False

db = SQLAlchemy(app)
counter = 1

class users(db.Model):
   id = db.Column('id',db.Integer,primary_key=True)
   name = db.Column('name',db.String(100))
   password = db.Column('password',db.String(100))
   role = db.Column('role',db.String(100))

   def __init__(self,id:int,name:str,password:str,role:str):
      self.name = name
      self.password = password
      self.id = counter
      self.role = role

usr = users(0,'Samantha (Root) Groves','password','Grey-hat')
db.session.add(usr)

@app.route('/',methods=['POST','GET'])
def frontPage():
   if request.method=='POST':
      user = request.form['Username']
      password = request.form['Password']
      found_user = users.query.filter_by(name=user,password=password).first()

      #if found_user:
         #return 'Hello',found_user['name']

      return "Hi"
   else:
      return render_template('mywebsite.html')

HTML页面代码

<html>
<style>
  button {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    font-size: medium;
    color: black;
    background-color: aliceblue;
    border-style: hidden;
    shape-outside: border-box;
    cursor: default;
    height: 36px;
    width: 144px;
    border-radius: 9px;
    top: 500px;
    left: 680px;
    position: absolute;
  }
  
  button:hover {
    background-color: orangered;
  }
</style>

<head>
  <title>Sign in/Sign up</title>
</head>

<body background="backColorWebsite.png">
  <form action="#" method="post">
    <label id="UsernameLabel" style="font-family: Verdana, Geneva, Tahoma, sans-serif; background-color: aliceblue;position:absolute; top: 250px;left:600px; width: 144px; height: 18px; border-radius:9px; text-align: center; font-size: medium; ">Username:</label>
    <input type="text" name="Username" style="font-family:Verdana, Geneva, Tahoma, sans-serif; background-color: aliceblue; position: absolute; top:250px;left:760px; width:144px; height:27px; border-radius: 9px;" maxlength="10"></input>
    <label id="PasswordLabel" style="font-family: Verdana, Geneva, Tahoma, sans-serif; background-color: aliceblue;position:absolute; top: 350px;left:600px; width: 144px; height: 18px; border-radius:9px; text-align: center; font-size: medium;">Password:</label>
    <input type="password" name="Password" style="font-family:Verdana, Geneva, Tahoma, sans-serif; background-color: aliceblue; position: absolute; top:350px;left:760px; width:144px; height:27px; border-radius: 9px;"></input>
    <button value="submit">Sign in</button>
  </form>
</body>

</html>

运行错误信息

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: users
[SQL: SELECT users.id AS users_id, users.name AS users_name, users.password AS users_password, users.role AS users_role
FROM users
WHERE users.name = ? AND users.password = ?
 LIMIT ? OFFSET ?]
[parameters: ('', '', 1, 0)]
127.0.0.1 - - [17/Nov/2023 01:36:40] "POST / HTTP/1.1" 500 -

解决方案

问题根源

你定义了users模型,但没有触发数据表的创建操作,所以查询时数据库里根本不存在这张表。教程说不用db.Table是对的——因为你用的是声明式模型(继承db.Model),ORM会自动根据模型类生成表结构,不需要手动用db.Table定义,但必须调用db.create_all()来实际创建表。

具体修复步骤

  1. 添加表创建逻辑
    在模型类定义后,调用db.create_all()创建所有模型对应的表,同时要在Flask应用上下文环境中执行这个操作。
  2. 修正模型的ID赋值逻辑
    已经把id设为primary_key=True,SQLAlchemy会自动生成自增ID,不需要手动用counter赋值,否则会导致重启程序后ID重复。
  3. 避免重复添加初始用户
    直接在全局代码添加用户会导致每次启动程序都重复添加,要先查询是否存在该用户再执行添加操作。
  4. 修正表单提交地址
    HTML表单的action="#"改为action="/",确保提交到正确的路由。

修正后的Flask代码

from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.secret_key = 'hello'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

class users(db.Model):
    id = db.Column('id', db.Integer, primary_key=True)
    name = db.Column('name', db.String(100), unique=True)  # 用户名设为唯一,避免重复
    password = db.Column('password', db.String(100))
    role = db.Column('role', db.String(100))

    def __init__(self, name: str, password: str, role: str):
        self.name = name
        self.password = password
        self.role = role

# 在应用上下文里创建表并添加初始用户
with app.app_context():
    db.create_all()
    # 检查初始用户是否存在,避免重复添加
    if not users.query.filter_by(name='Samantha (Root) Groves').first():
        usr = users('Samantha (Root) Groves', 'password', 'Grey-hat')
        db.session.add(usr)
        db.session.commit()

@app.route('/', methods=['POST', 'GET'])
def frontPage():
    if request.method == 'POST':
        user = request.form['Username']
        password = request.form['Password']
        found_user = users.query.filter_by(name=user, password=password).first()

        if found_user:
            return f'Hello, {found_user.name}'
        return "用户名或密码错误"
    else:
        return render_template('mywebsite.html')

修正后的HTML代码(仅调整提交地址)

<html>
<style>
  button {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    font-size: medium;
    color: black;
    background-color: aliceblue;
    border-style: hidden;
    shape-outside: border-box;
    cursor: default;
    height: 36px;
    width: 144px;
    border-radius: 9px;
    top: 500px;
    left: 680px;
    position: absolute;
  }
  
  button:hover {
    background-color: orangered;
  }
</style>

<head>
  <title>Sign in/Sign up</title>
</head>

<body background="backColorWebsite.png">
  <form action="/" method="post">
    <label id="UsernameLabel" style="font-family: Verdana, Geneva, Tahoma, sans-serif; background-color: aliceblue;position:absolute; top: 250px;left:600px; width: 144px; height: 18px; border-radius:9px; text-align: center; font-size: medium; ">Username:</label>
    <input type="text" name="Username" style="font-family:Verdana, Geneva, Tahoma, sans-serif; background-color: aliceblue; position: absolute; top:250px;left:760px; width:144px; height:27px; border-radius: 9px;" maxlength="10"></input>
    <label id="PasswordLabel" style="font-family: Verdana, Geneva, Tahoma, sans-serif; background-color: aliceblue;position:absolute; top: 350px;left:600px; width: 144px; height: 18px; border-radius:9px; text-align: center; font-size: medium;">Password:</label>
    <input type="password" name="Password" style="font-family:Verdana, Geneva, Tahoma, sans-serif; background-color: aliceblue; position: absolute; top:350px;left:760px; width:144px; height:27px; border-radius: 9px;"></input>
    <button type="submit">Sign in</button>
  </form>
</body>

</html>

关键说明

  • db.create_all()会自动扫描所有继承db.Model的类,在数据库中生成对应的数据表,这就是教程说不用db.Table的原因——声明式模型已经帮你封装了表结构定义。
  • 必须用app.app_context()包裹数据库操作,确保在Flask的应用上下文环境中执行,避免上下文错误。
  • 初始用户添加前先查询是否存在,防止每次启动程序都重复添加相同用户,导致主键冲突。

内容的提问来源于stack exchange,提问作者Root

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 02:15:58