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

使用Flask+SQLAlchemy时无法向数据库添加用户的问题求助

问题:Flask+SQLAlchemy添加用户到SQLite数据库失败,怀疑密码哈希逻辑问题

开发全栈个人项目,后端采用SQLite、SQLAlchemy和Flask框架。在models.py中定义了代表注册用户的User模型,但每次进入Flask Shell执行db.session.add()和db.session.commit()后,数据库中始终没有新增数据。怀疑问题出在使用bcrypt实现密码哈希的逻辑上,附上config.py和models.py代码,曾尝试修改密码哈希功能但问题仍未解决,求帮助。

# config.py
from flask import Flask 
from flask_restful import Api
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
from flask_bcrypt import Bcrypt
from dotenv import load_dotenv
import os

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///app.db"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.json.compact = False

metadata = MetaData(naming_convention={"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",})
db = SQLAlchemy(metadata=metadata)
migrate = Migrate(app,db)
db.init_app(app)

api = Api(app)

bcrypt = Bcrypt(app)

load_dotenv()

app.secret_key = os.getenv("SECRET_KEY")
# models.py
from config import db, bcrypt
from sqlalchemy_serializer import SerializerMixin
from sqlalchemy.ext.associationproxy import association_proxy


class User(db.Model, SerializerMixin):
    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String, nullable = False)
    email = db.Column(db.String, nullable = False)
    _password_hash = db.Column(db.String, nullable = False)

    def get_password_hash(self):
        return self._password_hash
    
    def set_password_hash(self, newPassword):
        byteObject = newPassword.encode("utf-8")
        newHash = bcrypt.generate_password_hash(byteObject)
        hashAsString = newHash.decode("utf-8")
        self._password_hash = hashAsString

    _password_hash = property(get_password_hash, set_password_hash)
         

    def authenticate(self, passedString):
        return bcrypt.check_password_hash(self._password_hash, passedString.encode("utf-8"))
    
    def __repr__(self):
        return f'ID: {self.id}, Username: {self.username}'

问题原因

核心问题是**User模型中用Python的property覆盖了SQLAlchemy的数据库列属性**,导致ORM无法正确识别_password_hash字段,进而在提交会话时无法将用户数据写入数据库:

  • 先定义_password_hash = db.Column(...),这是SQLAlchemy映射数据库列的关键属性
  • 随后执行_password_hash = property(get_password_hash, set_password_hash),直接覆盖了之前的列属性,使得SQLAlchemy不再将该字段视为数据库列,最终导致用户数据无法被持久化

另外需确认是否完成数据库迁移操作,若表结构未正确创建,数据也无法写入。

修复步骤

1. 修改User模型的密码哈希逻辑

将property名称改为password,避免覆盖数据库列属性,同时调整getter和setter:

# models.py
from config import db, bcrypt
from sqlalchemy_serializer import SerializerMixin
from sqlalchemy.ext.associationproxy import association_proxy


class User(db.Model, SerializerMixin):
    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String, nullable=False)
    email = db.Column(db.String, nullable=False)
    _password_hash = db.Column(db.String, nullable=False)

    # 调整property名称为password,避免覆盖数据库列
    @property
    def password(self):
        # 禁止直接获取密码
        raise AttributeError('密码不可直接访问')

    @password.setter
    def password(self, newPassword):
        byteObject = newPassword.encode("utf-8")
        newHash = bcrypt.generate_password_hash(byteObject)
        hashAsString = newHash.decode("utf-8")
        self._password_hash = hashAsString

    def authenticate(self, passedString):
        return bcrypt.check_password_hash(self._password_hash, passedString.encode("utf-8"))
    
    def __repr__(self):
        return f'ID: {self.id}, Username: {self.username}'

2. 执行数据库迁移(若未执行过)

在终端运行以下命令,确保表结构正确创建:

# 初始化迁移(仅第一次执行)
flask db init
# 生成迁移脚本
flask db migrate -m "add user table with password hash"
# 应用迁移到数据库
flask db upgrade

3. 在Flask Shell中正确创建用户

通过password属性设置密码,示例:

from config import app, db
from models import User

# 创建应用上下文
with app.app_context():
    # 创建用户
    user = User(username="testuser", email="test@example.com")
    user.password = "testpassword123"
    db.session.add(user)
    db.session.commit()
    # 验证是否添加成功
    print(User.query.all())

额外检查

  • 在Flask Shell操作时,注意观察是否有异常抛出(比如约束违反错误),根据异常信息进一步排查
  • 确认config.py中的数据库路径正确,app.db文件是否生成在项目根目录下

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:16:22