Sequelize.sync()仅在模型同文件定义时生效?Node.js项目问题咨询
问题:Sequelize.sync() 无法正常工作(分离模型文件时)
我正在开发一个连接PostgreSQL数据库的Node.js(TypeScript)应用,发现sequelize.sync()方法无法正常工作。当把Order模型单独放在order.ts文件中,注释掉database.ts里的模型定义后,从app.ts调用的syncDb方法就失效了。请问是否必须将所有模型定义放在同一文件中,还是我哪里操作有误?
相关代码文件
database.ts
import { Sequelize, DataTypes } from "sequelize"; import path from "path"; import { env } from "process"; import dotenv from 'dotenv'; import Order from "../models/order"; if(env.NODE_ENV === "production"){ dotenv.config({path: path.resolve("./dist", ".env")}); //console.log("prod:", env); }else{ dotenv.config({path: path.resolve("./.env")}); //console.log("dev:", path.resolve("./.env"), env); } export const sequelize = new Sequelize( env.DATABASE_NAME, env.DATABASE_USER, env.DATABASE_PASSWORD, { host: env.DATABASE_HOST, port: +env.DATABASE_PORT, dialect: "postgres", logging: false, pool: { max: 5, idle: 30000, acquire: 60000, }, define: { freezeTableName: true, }, } ); /* 若注释掉下方的Order定义,从app.ts调用的syncDb方法将失效 */ /* export const Order = sequelize.define("order", { // Model attributes are defined here firstName: { type: DataTypes.STRING, allowNull: false, }, lastName: { type: DataTypes.STRING, // allowNull defaults to true }, });*/ /* 此方法将从app.ts中调用 */ export const syncDb = async () => { try{ await sequelize.sync(); return true; }catch(err){ throw err; } };
app.ts
import express, { Request, Response, NextFunction } from "express"; import path from "path"; import { syncDb } from "./util/database"; const app = express(); syncDb() .then((res) => { app.listen(3000, () => { console.log("Server started successfully."); }); }) .catch((err) => { console.log("Database sync() error: ", err); });
order.ts
import { DataTypes } from "sequelize"; import { sequelize } from "../util/database"; const Order = sequelize.define("order", { // Model attributes are defined here firstName: { type: DataTypes.STRING, allowNull: false, }, lastName: { type: DataTypes.STRING, // allowNull defaults to true }, }); export default Order;
问题原因与解决方法
核心原因
Sequelize的sync()方法只会同步已经注册到Sequelize实例中的模型。当前你的app.ts仅导入了syncDb方法,但没有触发Order模型的加载——即使database.ts导入了Order,如果该导入未被实际使用,TypeScript/JavaScript的Tree Shaking机制会移除这个导入,导致模型从未被注册到Sequelize实例,sync()自然不会创建对应的表。
解决方法
不需要把所有模型放在同一文件,以下几种方案都能解决问题:
- 在app.ts中显式加载模型
在app.ts中添加模型的导入语句,确保模型被加载并注册:
import express, { Request, Response, NextFunction } from "express"; import path from "path"; import { syncDb } from "./util/database"; import "./models/order"; // 显式加载Order模型 const app = express(); // ... 后续代码不变
- 确保database.ts中的模型导入不被Tree Shaking移除
如果想保持app.ts简洁,可以在database.ts中添加一行代码,确保导入的Order被使用:
import Order from "../models/order"; // 添加这行,避免导入被Tree Shaking移除 const _ = Order;
- 创建统一的模型入口文件(推荐)
创建models/index.ts来统一管理所有模型:
import Order from "./order"; // 后续新增的模型都在这里导入 // 可以选择导出模型,方便其他地方使用 export { Order };
然后在app.ts或database.ts中导入这个入口文件:
import "./models/index";
这种方式更易于维护,尤其当模型数量增多时。
内容的提问来源于stack exchange,提问作者Liang-Liang Han
相关产品推荐
相关产品推荐

