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

更新数据库条目时触发‘Expected Bytes’错误的排查求助

解决PUT请求更新用户时的"Expected Bytes"密码异常问题

兄弟,我帮你捋清楚这个问题——你遇到的Expected Bytes异常根本不是查询对象的类型问题(你编辑1的猜测不对),核心出在密码哈希环节接收了无效参数,咱们一步步解决:

问题根源

你的set_password方法调用的generate_password_hash(应该是Werkzeug的哈希函数吧?)要求传入非空的字符串类型参数。但更新用户场景下,用户可能只想改用户名/邮箱,没传Password字段,这时候data['Password']要么是None,要么直接触发KeyError,传给哈希函数就会抛出Expected Bytes异常。而注册时没问题,是因为注册流程肯定强制用户输入了密码,不会出现这种情况。

一步步修复方案

1. 先修正API模型:让Password成为可选字段

你的UserModel里把Password设成了必填,但更新场景下用户不需要每次都改密码,先改模型:

UserModel = api.model('User', {
    'Username': fields.String(required=True),
    'Email Address': fields.String(required=True),
    'Password': fields.String(required=False)  # 改为可选,允许不传
})

2. 修改路由逻辑:只在需要时更新密码

不能不管三七二十一就调用set_password,要先判断请求里有没有传有效的密码:

@UserNS.expect(UserModel)
@token_required
def put(self):
    """Updates the user details associated with the API token."""
    # 先处理Token的边界情况,避免KeyError
    token = request.headers.get('Token')
    if not token:
        return {'Message': 'Token is required!'}
        
    data = request.get_json()
    if not data:
        return jsonify({'message': 'Please enter some user data'})
    
    update_user = User.query.filter_by(api_token=token).first()
    if not update_user:
        return {'Message': 'User not found!'}
    
    print("Updating user details")
    print("Current: " + update_user.username + " " + update_user.email)
    print("New: " + data["Username"] + " " + data["Email Address"])
    
    try:
        update_user.username = str(data["Username"])
        update_user.email = str(data['Email Address'])
        
        # 只有当Password字段存在且不为空字符串时,才执行密码更新
        if 'Password' in data and data['Password'].strip():
            print("Trying to save password...")
            update_user.set_password(data['Password'])
        
        db.session.commit()
        return {'Message': 'Record updated!'}
    except Exception as e:
        print(e)
        db.session.rollback()  # 异常一定要回滚事务,避免脏数据
        return {'Message': f'Update failed: {str(e)}'}  # 返回具体错误,方便调试

3. 确认set_password方法的正确性

确保你的密码哈希方法是正确的,用Werkzeug的函数(Flask-Login依赖这个):

from werkzeug.security import generate_password_hash

class User(UserMixin, db.Model):
    # ...你的其他字段定义...
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

额外优化小建议

  • 不要直接用str(data["Username"]),可以加个简单校验,比如检查长度、是否包含非法字符,避免存入无效数据。
  • 捕获异常时别只返回模糊的“invalid”提示,把具体错误返回给前端,方便调试(比如用户名重复的错误)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:39:08