这次简单分享一个在学习过程中一个踩坑爬坑的故事。
起因是笔者在看一本讲 Egg 的书,但是书中介绍的方法可能因为时间的推移,在笔者跟着学习时已经无法实现正常功能了。书中说 egg-sequelize 的版本有问题,要使用自定义的 sequelize-cli。 书中手动创建了 rc, config 文件, 和 migration, model, seeder 目录。
跳坑
结果到创建 model 的时候出了问题。
./node_modules/.bin/sequelize model:generate --name User
但是我自己亲手敲的时候会报错,提示缺少attributes参数
此时我的第一反应是,是不是 cli 有更新,我看下用当前版本的 cli 应该怎么做。
摸索
参考 cli 文档,我补全了attributes参数,并成功生成了 model 和 migration。 生成的 Model 大概这个样子:
"use strict";
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define(
"User",
{
username: DataTypes.STRING
},
{}
);
return User;
};
于是运行的时候,就会报错
TypeError: sequelize.define is not a function
因为此时的 sequelize,实际上是 Egg 的 Application, app 上从来没定义过 define
爬坑
仔细翻阅插件 egg-sequelize 的 readme 发现线索
Read the tutorials to see a full example.
可用的 Model 其实应该长这个样子:
// app/model/user.js
module.exports = app => {
const { STRING, INTEGER, DATE } = app.Sequelize;
const User = app.model.define("user", {
login: STRING,
name: STRING(30),
password: STRING(32),
age: INTEGER,
last_sign_in_at: DATE,
created_at: DATE,
updated_at: DATE
});
User.findByLogin = async function(login) {
return await this.findOne({
where: {
login: login
}
});
};
// don't use arraw function
User.prototype.logSignin = async function() {
return await this.update({ last_sign_in_at: new Date() });
};
return User;
};
然后按照官方的 tutorial 走下来发现,Migration 和 Model 是分开生成的,Model 手动创建。Migration 和 Model 中的内容部分重合。像这样:
// user migraition
"use strict";
module.exports = {
up: async (queryInterface, Sequelize) => {
const { INTEGER, DATE, STRING } = Sequelize;
await queryInterface.createTable("users", {
// 看这里看这里 <---------
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: STRING(30),
age: INTEGER,
created_at: DATE,
updated_at: DATE
});
},
down: async queryInterface => {
await queryInterface.dropTable("users");
}
};
// user model
"use strict";
module.exports = app => {
const { STRING, INTEGER, DATE } = app.Sequelize;
const User = app.model.define("user", {
// 看这里看这里 <---------
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: STRING(30),
age: INTEGER,
created_at: DATE,
updated_at: DATE
});
return User;
};
后续打算写个小工具,用 Migration 的内容自动生成 app.model.define 的参数
总结
回顾了一下踩坑经历,一开始的注意力全在 cli 那边,却忽视了 sequelize 的使用场景 egg,也就忽视了 egg-sequelize 的存在。所以正确的打开姿势是先在官方文档中找答案,读文档,读文档,读文档。