1.TypeError: Class constructor Model cannot be invoked without 'new'
- 故事背景:sequelize + typescript + ES2015
- 原因分析:不支持 ES2015 语法
- 解决方案:Typescript => ES6 => ES5
tsconfig.json
将 compilerOptions 配置中的 target 变更成 es6
babel.config.json
在项目根目录下下 babel.config.json 配置文件中添加预设 @babel/preset-env
package.json
- 在 devDependencies 中添加 @babel/node 和 @babel/preset-env
- 使用 babel-node 启动项目
tsc && babel-node build/index.js
2.Cannot read properties of undefined (reading 'length')
- 错误定位在 sequelize/lib/model.js 的 141 行 primaryKeyAttributes 不存在。
if (this.constructor.primaryKeyAttributes.length) {
this.constructor.primaryKeyAttributes.forEach(primaryKeyAttribute => {
if (!Object.prototype.hasOwnProperty.call(defaults, primaryKeyAttribute)) {
defaults[primaryKeyAttribute] = null;
}
});
}
- 错误原因:没有调用 sequelize 初始化方法。泪崩。
const sequelize = new Sequelize(config.database, config.username, config.password, {
host: config.host,
dialect: config.dialect,
});
3. Role is associated to User using an alias. You've included an alias (roles), but it does not match the alias(es) defined in your association (Roles).
- 需求背景:user 和 role 是多对多的关系。获取用户信息的时候连带将用户所有的角色信息都拿到。
- 原因分析:在获取 user 信息的时候使用了别名 roles。但是在定义的时候没有定义别名 roles。
await User.findAll({
include: [
{
model: Role,
as: "roles",
},
],
});
- 解决方案:
User.belongsToMany(Role, {
through: UserRole,
as: 'roles'
});
4. 一对一关系关联新增失败
user 和 auth 之间是一对一的关系
UserModel.belongsTo(AuthModel);
AuthModel.hasOne(UserModel);
当新增 auth 的时候调用 setUser 方法报错。
const auth = await Auth.create({
username: username,
password: password,
});
await auth.setUser({
user_name: username
});
错误原因:setUser 接受的参数应该是一个 Model 类型的对象。
解决方案:创建一个 Model 类型的 user,然后调用 setUser 方法。
await auth.setUser(
User.create({
user_name: username,
})
);
5. SequelizeEagerLoadingError
user 和 role 之间是多对多的关系
RoleModel.belongsToMany(UserModel, {
through: "UserRole",
});
UserModel.belongsToMany(RoleModel, {
through: "UserRole",
});
获取 user 时期望预加载 role 的信息
await User.findOne({
where: {
user_id: id,
},
include: [
{
model: Role,
as: "roles",
},
],
});
发现报错 SequelizeEagerLoadingError
报错原因是无法识别 roles 别名。使用别名的前提是定义别名,使用别名的前提是定义别名,使用别名的前提是定义别名。
可是在user 和 role 的关联定义中并没有发现有别名的定义。
解决方案:
RoleModel.belongsToMany(UserModel, {
through: "UserRole",
as: "users",
});
UserModel.belongsToMany(RoleModel, {
through: "UserRole",
as: "roles",
});
6. 数据库连接成功但是没有创建表
const sequelize = new Sequelize(database, username, password, {
dialect: "mysql",
host: "localhost",
port: 3306,
define: {
freezeTableName: true,
},
sync: {
force: true
}
});
...
原因是:在创建 sequelize 实例时已经设置了
sync: { force: true }
此时,将表同步到数据库中,此时没有表,因此是空的。应该先建立数据表,然后调用同步方法。
const sequelize = new Sequelize(database, username, password, {
dialect: "mysql",
host: "localhost",
port: 3306,
define: {
freezeTableName: true,
},
});
...
定义 schema 的逻辑
...
try {
await sequelize.authenticate();
// await sequelize.sync({ force: true });
console.log("Connection has been established successfully.");
} catch (error) {
console.error("Unable to connect to the database:", error);
}
7. createError (createError.js:17:15)
很明显,创建时报错。怎么就报错了呢,没问题啊。
router.get("/user", async function (req, res) {
try {
const res = await User.findAll();
res.status(200).send(res);
} catch (err) {
res.status(500).send(err);
}
});
仔细一看发现,send(res)有问题。查询的结果被赋值给变量 res。可是 res 可是 response 啊。重写了 res,使用重写后的 res 返回请求。正确的做法:
router.get("/user", async function (req, res) {
try {
const data = await User.findAll();
res.status(200).send(data);
} catch (err) {
res.status(500).send(err);
}
});