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

TypeScript中Sequelize freezeTableName不生效问题求助

解决Sequelize查询PostgreSQL时"relation auth.User does not exist"错误

环境版本

  • node: 18.12.1
  • sequelize: 6.29.0
  • Typescript: 4.9.5

Sequelize实例配置

export const sequelize = new Sequelize(config.db.DB_NAME, config.db.DB_USER, config.db.DB_PASS, {
    host: 'localhost',
    dialect: 'postgres',
    port: 5432,
    define: {
        freezeTableName: true,
        underscored: true,
    }
});

用户模型代码

// TYPE DECLARATION and COLUMN NAME DECLARATION...
class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
    declare id: CreationOptional<string>;
    declare first_name: string;
    declare last_name: string;
    declare user_name: string;
    declare email: string;
    declare password: string;
    declare last_login: CreationOptional<Date>;
    declare is_active: CreationOptional<boolean>;
    declare is_superadmin: CreationOptional<boolean>;
    declare created_at: CreationOptional<Date>;
    declare updated_at: CreationOptional<Date>;

    fullName(): string {
        return [this.first_name, this.last_name].join(' ');
    }
}

User.init({
    id: {
        type: DataTypes.UUID,
        allowNull: false,
        defaultValue: DataTypes.UUIDV4,
        primaryKey: true,
    },

    first_name: {
        type: DataTypes.STRING,
        allowNull: false
    },
    last_name: {
        type: DataTypes.STRING,
        allowNull: false
    },
    user_name: {
        type: DataTypes.STRING,
        allowNull: false
    },
    email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true,
        validate: {
            isEmail: { msg: "invalid email, please provide valid email address." }
        },
    },
    password: {
        type: DataTypes.STRING,
        allowNull: false,
        set(value: string) {
            const pass = hashSync(value, 10);
            this.setDataValue("password", pass)
        }
    },
    last_login: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
    },
    is_active: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: false,
    },
    is_superadmin: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: false,
    },

    created_at: DataTypes.DATE,
    updated_at: DataTypes.DATE,

}, {
    sequelize,
    schema: "auth",
    // freezeTableName: true,
    // modelName: 'User',
    // tableName: 'user',
    createdAt: "created_at",
    updatedAt: "updated_at"
});

export default User;

报错信息

error: relation "auth.User" does not exist

生成的SQL查询

Executing (default): SELECT "id", "first_name", "last_name", "user_name", "email", "password", "last_login", 
"is_active", "is_superadmin", "created_at", "updated_at" FROM "auth"."User" AS "User" WHERE "User"."first_name" = 'nawaraj' LIMIT 1;

问题分析

你误解了freezeTableName的作用:它只是阻止Sequelize将模型名复数化作为表名,并不会自动将表名转为小写。PostgreSQL对标识符大小写敏感:如果创建表时未加双引号,表名会被自动转为小写(比如你实际数据库里的表是auth.user),但Sequelize生成的查询用了带双引号的"User",这会严格匹配大写表名,导致找不到对应关系。

解决方案

在模型的init配置里显式指定tableName: 'user',覆盖默认的模型名作为表名的行为:

修改模型的init配置部分:

}, {
    sequelize,
    schema: "auth",
    freezeTableName: true, // 可以保留,确保表名不被复数化
    tableName: 'user', // 显式指定小写表名
    createdAt: "created_at",
    updatedAt: "updated_at"
});

这样Sequelize生成的SQL会查询auth.user,和数据库里的实际表名匹配,就能解决这个错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:08:15