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

Flask SQLAlchemy UUID主键格式异常,如何恢复正确格式并正常使用?

解决Flask REST API中UUID主键的查询、返回及接口适配问题

问题根源

  • 路由使用<int:id>强制限制参数为整数,无法接收UUID格式的字符串
  • Marshmallow的fields.Int会把UUID字符串强制转换为大整数,最终以科学计数法返回
  • 查询/删除逻辑按整数处理ID,与数据库中存储的UUID类型不匹配

分步解决方案

1. 修改路由参数类型

将所有涉及用户ID的路由(GET/DELETE等)中的<int:id>改为<string:id>,允许接收UUID格式的字符串参数:

# 原路由
@app.route('/users/<int:id>', methods=['GET'])
def get_user(id):
    pass

# 修改后路由
@app.route('/users/<string:id>', methods=['GET'])
def get_user(id):
    pass

2. 更新Marshmallow Schema的id字段定义

把fields.Int替换为fields.UUID(推荐,自动验证UUID格式)或fields.String,确保返回标准UUID字符串:

from marshmallow import Schema, fields
import uuid

class UserSchema(Schema):
    # 替换原有的fields.Int()
    id = fields.UUID()
    # 也可以用String类型:id = fields.String()
    
    # 其他字段保持不变
    username = fields.String(required=True)
    email = fields.Email(required=True)

3. 适配查询/删除的UUID逻辑

在处理查询、删除操作时,先把传入的字符串ID转换为UUID对象,再与数据库中的主键匹配:

import uuid
from flask import abort, jsonify
from your_app.models import UserModel
from your_app.schemas import UserSchema
from your_app.extensions import db

user_schema = UserSchema()

@app.route('/users/<string:id>', methods=['GET'])
def get_user(id):
    try:
        # 将字符串转为UUID对象
        user_uuid = uuid.UUID(id)
    except ValueError:
        # 非法UUID格式返回400错误
        abort(400, description="Invalid UUID format")
    
    user = UserModel.query.get(user_uuid)
    if not user:
        abort(404, description="User not found")
    
    return jsonify(user_schema.dump(user))

@app.route('/users/<string:id>', methods=['DELETE'])
def delete_user(id):
    try:
        user_uuid = uuid.UUID(id)
    except ValueError:
        abort(400, description="Invalid UUID format")
    
    user = UserModel.query.get(user_uuid)
    if not user:
        abort(404, description="User not found")
    
    db.session.delete(user)
    db.session.commit()
    
    return jsonify({"message": "User deleted successfully"}), 200

4. (可选)全局UUID参数验证

如果多个路由需要处理UUID参数,可通过before_request统一验证,避免重复代码:

from flask import abort, request
import uuid

@app.before_request
def validate_uuid_params():
    if 'id' in request.view_args:
        try:
            uuid.UUID(request.view_args['id'])
        except ValueError:
            abort(400, description="Invalid UUID format")

验证效果

  • GET接口返回的id字段将显示为标准UUID字符串(如465dc674-ca3a-11ed-afa1-0242ac120002),不再是科学计数法
  • 传入合法UUID可正常执行查询、删除操作
  • 非法格式的ID参数会触发400错误,避免无效数据库查询

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 13:37:23