Flask操作PostgreSQL多对多表报execute_values意外fetch参数错误
问题解决方案
报错根因与修复
你遇到的TypeError: execute_values() got an unexpected keyword argument 'fetch'错误,是SQLAlchemy与psycopg2版本不兼容导致的:SQLAlchemy 1.4+版本调整了PostgreSQL方言层的参数传递逻辑,当使用的psycopg2-binary版本低于2.8.6时,就会出现参数不识别的问题。
修复方法:
执行以下命令升级psycopg2版本即可:
pip install -U psycopg2-binary>=2.8.6
业务代码逻辑修复
除了版本兼容问题,你现有代码还存在逻辑错误,即便版本升级后也无法实现批量绑定权限的需求,需要做以下调整:
问题点
你的RolePermissionsCreateSchema继承自Role的ModelSchema,调用load方法返回的是一个全新的Role实例,而非你从数据库查询到的已存在的角色实例,直接add这个新实例会引发主键冲突、数据覆盖等问题。
修复方案
方案1:调整现有Schema的使用逻辑
修改视图层的代码,将Schema加载得到的权限列表赋值给已存在的角色对象:
def post(self, id, **kwargs): try: role = Role.query.filter_by(id=id).first_or_404() post_data = request.get_json() loaded_data = RolePermissionsCreateSchema(partial=True).load(post_data) # 覆盖现有权限,如果需要追加则改成 role.permissions.extend(loaded_data['permissions']) role.permissions = loaded_data['permissions'] db.session.add(role) db.session.commit() return jsonify(data=RoleSchema().dump(role), status=True), 201 # 其余异常处理逻辑保持不变
方案2:优化Schema定义(更推荐)
你不需要用ModelSchema来做参数校验,直接写普通Schema接收权限ID列表,再批量查询权限对象绑定即可,逻辑更清晰也避免不必要的问题:
- 调整Schema定义:
class RolePermissionsCreateSchema(ma.Schema): permissions = fields.List(fields.Integer(), required=True) # 可选:增加验证逻辑确保权限ID合法 @ma.validates('permissions') def validate_permission_ids(self, value): exist_cnt = Permission.query.filter(Permission.id.in_(value)).count() if exist_cnt != len(value): raise ma.ValidationError("存在无效的权限ID")
- 调整视图层逻辑:
def post(self, id, **kwargs): try: role = Role.query.filter_by(id=id).first_or_404() post_data = request.get_json() loaded_data = RolePermissionsCreateSchema().load(post_data) # 批量查询权限对象 permissions = Permission.query.filter(Permission.id.in_(loaded_data['permissions'])).all() # 追加权限,要覆盖的话改成 role.permissions = permissions role.permissions.extend(permissions) db.session.add(role) db.session.commit() return jsonify(data=RoleSchema().dump(role), status=True), 201 # 其余异常处理逻辑保持不变
内容的提问来源于stack exchange,提问作者A. Josh
相关产品推荐
相关产品推荐

