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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 04:45:00