sqlalchemy_utils PasswordType字段约束失效,求教添加可行约束方案
关于SQLAlchemy-Utils PasswordType添加数据库约束的问题
嘿,这个问题我之前踩过坑!咱们来理清楚为什么你的约束没生效,以及正确的解决方式:
为什么你的CheckConstraint不生效?
你添加的CheckConstraint('length("password") >= 7')约束针对的是数据库中存储的哈希后密码,而不是你输入的原始密码。SQLAlchemy-Utils的PasswordType会自动将原始密码哈希成固定长度的字符串(比如你用的pbkdf2_sha512生成的哈希串长度是60左右,和你设置的max_length=60一致),所以这个约束其实一直处于满足状态,完全达不到验证原始密码长度的目的。
正确的解决方案
因为密码哈希后无法反向推导原始长度,所以数据库层面的约束无法验证原始密码的长度,我们需要在业务逻辑层或者模型字段验证层来做这件事:
方案1:使用SQLAlchemy的validates装饰器做字段验证
这是最推荐的方式,直接在模型里对原始密码做长度校验:
from sqlalchemy.orm import validates from sqlalchemy_utils import PasswordType from your_app import db class SomeModel(db.Model): password = db.Column( PasswordType( max_length=60, schemes=[ 'pbkdf2_sha512', 'md5_crypt' ], deprecated=['md5_crypt'] ), unique=False, nullable=False, ) @validates('password') def validate_password_length(self, key, raw_password): # 校验原始密码的长度 if len(raw_password) < 7: raise ValueError("密码长度不能少于7个字符") return raw_password
当你给SomeModel的password字段赋值时,这个验证器会自动触发,不符合长度要求会直接抛出异常。
方案2:在业务逻辑层做校验
如果你更倾向于在视图/服务层处理验证,也可以在接收用户输入时直接校验:
# 比如在用户注册的视图函数里 raw_password = request.form.get('password') if len(raw_password) < 7: return jsonify({"error": "密码长度不能少于7个字符"}), 400 # 然后再创建模型实例 user = SomeModel(password=raw_password) db.session.add(user) db.session.commit()
额外提醒
PasswordType的max_length参数是用来限制哈希后密码的存储长度,和原始密码长度无关,所以不需要通过它来控制原始密码的长度哦。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

