在 Egg.js 中使用 sequelize 建立 Model 踩坑記

此次簡單分享一個在學習過程當中一個踩坑爬坑的故事。html

原由是筆者在看一本講 Egg 的書,可是書中介紹的方法可能由於時間的推移,在筆者跟着學習時已經沒法實現正常功能了。書中說 egg-sequelize 的版本有問題,要使用自定義的 sequelize-cli。 書中手動建立了 rc, config 文件, 和 migration, model, seeder 目錄。node

跳坑

結果到建立 model 的時候出了問題。bash

./node_modules/.bin/sequelize model:generate --name User
複製代碼

可是我本身親手敲的時候會報錯,提示缺乏attributes參數app

此時個人第一反應是,是否是 cli 有更新,我看下用當前版本的 cli 應該怎麼作。async

摸索

參考 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 上歷來沒定義過 defineui

爬坑

仔細翻閱插件 egg-sequelize 的 readme 發現線索this

Read the tutorials to see a full example.spa

可用的 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 的存在。因此正確的打開姿式是先在官方文檔中找答案,讀文檔,讀文檔,讀文檔。

相關文章
相關標籤/搜索