如何在Flask模型的id主键字段设置默认UUID值?
正确设置Flask-SQLAlchemy模型UUID默认值的方法
你当前的写法server_default=str(uuid.uuid4())存在核心问题:模型定义时uuid.uuid4()会被立即执行并转为固定字符串,数据库将这个值设为列的全局默认值,导致所有新用户的id完全重复。以下是两种可靠的解决方式:
方案一:利用数据库内置函数生成UUID(以MySQL为例)
通过SQLAlchemy的func调用MySQL原生的UUID()函数,让数据库在插入新行时自动生成唯一UUID:
from sqlalchemy import func from flask_sqlalchemy import SQLAlchemy from flask_login import UserMixin db = SQLAlchemy() class User(db.Model, UserMixin): id = db.Column(db.String(36), primary_key=True, server_default=func.uuid()) email = db.Column(db.String(150), unique=True, nullable=False) password = db.Column(db.String(255), nullable=False) first_name = db.Column(db.String(150), nullable=False) last_name = db.Column(db.String(150), nullable=False) image_file = db.Column(db.String(60), nullable=False, default='default.jpg') created_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
MySQL的UUID()函数生成的是标准36位带横线的UUID字符串,完全匹配你定义的字段长度。
方案二:在应用层生成UUID
如果不想依赖数据库的特定函数,可通过SQLAlchemy的default参数传入函数引用(注意不要加括号,避免提前执行),每次创建User实例时自动生成新UUID:
import uuid from flask_sqlalchemy import SQLAlchemy from flask_login import UserMixin db = SQLAlchemy() class User(db.Model, UserMixin): id = db.Column(db.String(36), primary_key=True, default=lambda: str(uuid.uuid4())) email = db.Column(db.String(150), unique=True, nullable=False) password = db.Column(db.String(255), nullable=False) first_name = db.Column(db.String(150), nullable=False) last_name = db.Column(db.String(150), nullable=False) image_file = db.Column(db.String(60), nullable=False, default='default.jpg') created_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
这里用lambda包裹str(uuid.uuid4()),确保每次创建实例时都会执行一次UUID生成逻辑,得到唯一值。
两种方案的区别
- 数据库端生成:即使通过原生SQL插入数据,数据库也会自动填充UUID,适合多应用共享同一数据库的场景。
- 应用层生成:UUID逻辑完全由Python代码控制,跨数据库兼容性更好,无需依赖数据库的特定函数。
内容的提问来源于stack exchange,提问作者weaver
相关产品推荐
相关产品推荐

