更新数据库条目时触发‘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
相关产品推荐
相关产品推荐

