Sequelize查询返回随机UUID而非存储值的问题排查
查询Sequelize模型时ID返回随机UUID而非存储值的问题
问题描述
从数据库查询数据时,返回的模型实例ID是随机生成的UUID,而非数据库中存储的正确值。但使用raw: true参数查询时,能得到正确的ID(此时返回普通对象,无Sequelize方法)。
模型定义
import { Column, DataType, Default, Model, PrimaryKey, Table, IsLowercase, Unique } from 'sequelize-typescript' @Table({ underscored: true, paranoid: true, timestamps: true }) export abstract class BaseModel<T> extends Model<T> { @PrimaryKey @Default(DataType.UUIDV4) @Column(DataType.UUID) id: string @Column readonly createdAt: Date @Column readonly updatedAt: Date @Column readonly deletedAt: Date constructor(input?: any) { super() if (input) { Object.assign(this, input) } } } @Table export default class Foo extends BaseModel<Tag> { @Unique @IsLowercase @Column(DataType.STRING(32)) name: string toJSON(): object { return { id: this.id, name: this.name, updatedAt: this.updatedAt, } } }
复现示例
// 创建并查询 const f = await Foo.findAll(); console.log("created id", f.id); // => created id cda0f763-2384-4116-970d-f6418678787c const foundFoo= await Foo.findOne(); console.log("found id", foundFoo.id); // => found id 6ae277c7-1797-4bfa-a9dd-c893d004a151 // 使用raw:true查询 const f = await Foo.findAll(); console.log("created id", f.id); // => created id cda0f763-2384-4116-970d-f6418678787c const foundFoo= await Foo.findOne({ raw: true }); console.log("found id", foundFoo.id); // => found id cda0f763-2384-4116-970d-f6418678787c
运行环境
- Node.js v18.18.2
- Sequelize ^6.37.1
- sequelize-typescript ^2.1.3
- Linux系统
原因分析
问题出在BaseModel中id字段的@Default(DataType.UUIDV4)注解。当Sequelize从数据库读取数据并创建模型实例时,会自动执行默认值逻辑,生成新的UUID覆盖从数据库获取的原始ID。而使用raw: true时,Sequelize直接返回数据库的原始数据,不会创建模型实例,因此不会触发默认值生成逻辑,能得到正确的ID。
解决方案
方案1:移除@Default注解
如果数据库端已经负责生成UUID(比如设置了列默认值),或者你在创建新记录时手动生成UUID,直接移除@Default注解即可:
@Table({ underscored: true, paranoid: true, timestamps: true }) export abstract class BaseModel<T> extends Model<T> { @PrimaryKey @Column(DataType.UUID) id: string // ... 其他字段保持不变 }
方案2:保留默认值但限制仅创建时生效(可选)
如果需要在创建新记录时自动生成UUID,同时避免查询时覆盖现有ID,可以确保默认值仅在实例为新对象时生效。不过更稳妥的方式是直接移除@Default,改为在创建记录时手动生成或依赖数据库默认值。
额外修复:泛型参数错误
注意到Foo类继承时使用了BaseModel<Tag>,但Tag未定义,应改为对应类型,比如BaseModel<Foo>:
@Table export default class Foo extends BaseModel<Foo> { // ... 字段保持不变 }
内容的提问来源于stack exchange,提问作者PatientOtter
相关产品推荐
相关产品推荐

