Sequelize bulkCreate枚举类型转换名称错误,如何修正?
问题
我需要初始化数据库表,以下是使用sequelize-auto生成的Player模型定义:
export class Player extends Model<PlayerAttributes, PlayerCreationAttributes> implements PlayerAttributes { player_id!: string jersey_number!: number roles!: Role[] first_name!: string last_name!: string country_id!: string team_id!: string traits!: Trait[] /** ASSOCIATIONS **/ static initModel (sequelize: Sequelize.Sequelize): typeof Player { return Player.init({ player_id: { type: DataTypes.UUID, allowNull: false, primaryKey: true }, jersey_number: { type: DataTypes.INTEGER, allowNull: false }, roles: { type: DataTypes.ARRAY(DataTypes.ENUM('SETTER', 'LIBERO', 'OUTSIDE_HITTER', 'OPPOSITE_HITTER', 'MIDDLE_BLOCKER', 'DEFENSIVE_SPECIALIST')), allowNull: false }, first_name: { type: DataTypes.STRING, allowNull: false }, last_name: { type: DataTypes.STRING, allowNull: false }, country_id: { type: DataTypes.UUID, allowNull: false, references: { model: 'Country', key: 'country_id' } }, team_id: { type: DataTypes.UUID, allowNull: false, references: { model: 'Team', key: 'team_id' } }, traits: { type: DataTypes.ARRAY(DataTypes.ENUM('MARKSMAN', 'MOVING_WALL', 'MASTER_MIND', 'METEOR_SERVE', 'VIGOROUS', 'GUARDIAN')), allowNull: false, } }, { sequelize, tableName: 'Player', schema: 'public', timestamps: false, indexes: [ { name: 'Player_pk', unique: true, fields: [ { name: 'player_id' }, ] }, ] }) } }
执行单个create操作时可成功运行,对应的SQL语句如下:
Executing (default): INSERT INTO "public"."Player" ("player_id","jersey_number","roles","first_name","last_name","country_id","team_id","traits") VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "player_id","jersey_number","roles","first_name","last_name","country_id","team_id","traits";
但使用bulkCreate时出现错误,错误信息如下:
{ sql: `INSERT INTO "public"."Player" ("player_id","jersey_number","roles","first_name","last_name","country_id","team_id","traits") VALUES ('19bc996a-b386-446d-bbd1-5fc34820993a',96,ARRAY['SETTER','OPPOSITE_HITTER','OUTSIDE_HITTER']::"public"."enum_Player_roles"[],'Gabriel','Ward','44a3ac8c-e324-4206-b564-efc93aa81bc9','884b32c1-a5ab-45ea-b5ba-806e3f20381a',ARRAY['METEOR_SERVE']::"public"."enum_Player_traits"[]) RETURNING "player_id","jersey_number","roles","first_name","last_name","country_id","team_id","traits";`, parameters: undefined }, original: error: type "public.enum_Player_roles[]" does not exist
错误原因是Sequelize错误地将枚举数组类型转换为了自动生成的名称,正确的类型名应该是:
"public.enum_Player_roles[]"改为"public.role[]""public.enum_Player_traits[]"改为"public.trait[]"
请问如何让Sequelize使用正确的类型名称?
解决方案
问题出在模型中定义ENUM类型时没有指定数据库中已存在的枚举名称,导致Sequelize在批量插入时自动生成了enum_<表名>_<字段名>格式的类型名,与数据库实际存在的role和trait枚举类型不匹配。
修改模型中ENUM类型的定义,为每个ENUM添加name属性,指定数据库中对应的枚举类型名:
// 修改roles字段的ENUM定义 roles: { type: DataTypes.ARRAY(DataTypes.ENUM({ name: 'role', // 指定数据库中已存在的枚举类型名 values: ['SETTER', 'LIBERO', 'OUTSIDE_HITTER', 'OPPOSITE_HITTER', 'MIDDLE_BLOCKER', 'DEFENSIVE_SPECIALIST'] })), allowNull: false }, // 修改traits字段的ENUM定义 traits: { type: DataTypes.ARRAY(DataTypes.ENUM({ name: 'trait', // 指定数据库中已存在的枚举类型名 values: ['MARKSMAN', 'MOVING_WALL', 'MASTER_MIND', 'METEOR_SERVE', 'VIGOROUS', 'GUARDIAN'] })), allowNull: false }
这样修改后,Sequelize在生成批量插入的SQL时,会使用指定的role和trait枚举类型名,而不是自动生成的enum_Player_roles和enum_Player_traits,就能匹配数据库中实际存在的类型,解决bulkCreate的报错问题。
另外需要注意:
- 确保数据库中确实存在
public.role和public.trait这两个枚举类型 - 如果是通过sequelize-auto生成的模型,工具默认不会带上ENUM的
name属性,需要手动补充这个配置
内容的提问来源于stack exchange,提问作者Francisco Farías
相关产品推荐
相关产品推荐

