Sequelize-模型与迁移

时间:2020-07-19 19:59:40

标签: mysql node.js model migration sequelize.js

[已解决!]

我已经在互联网上进行了很多研究,并发现了与我类似的问题。但是,我找不到解决问题的正确方法。请帮忙。

我正在使用 Sequelize v6 。使用模型和迁移时遇到一些麻烦。

我所做的事情:

我使用 sequelize cli 生成了角色模型。它为我提供了models/role.js中的以下代码。

"use strict";
const { Model } = require("sequelize");

module.exports = (sequelize, DataTypes) => {
  class Role extends Model {
    static associate(models) {
      // define association here
    }
  }

  Role.init(
    {
      name: DataTypes.STRING,
      description: DataTypes.STRING,   },
    {
      sequelize,
      modelName: "roles",
    }
  );

  return Role;
};

我还在migrations/timestamp-create-role.js中获得了该模型的迁移文件。

"use strict";

module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable(
      "roles", // <- I've changed this from Roles to roles because I want the MySQL convention.
      {
        roleId: {
          allowNull: false,
          autoIncrement: true,
          field: "role_id",
          primaryKey: true,
          type: Sequelize.INTEGER,
        },
        name: {
          allowNull: false,
          type: Sequelize.STRING(30),
        },
        description: {
          type: Sequelize.STRING(50),
        },
        createdAt: {
          allowNull: false,
          field: "created_at",
          type: Sequelize.DATE,
        },
        updatedAt: {
          allowNull: false,
          field: "updated_at",
          type: Sequelize.DATE,
        },
      },
      {
        underscored: true,
      }
    );
  },

  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable("roles");
  },
};

我在MySQL中得到的东西

通过运行上述迁移,我得到了包含以下列的roles表:

role_id, name, created_at, updated_at很好。那就是我想要的MySQL数据库。

阅读角色

/controllers/roles.js

const Role = require("../models").roles;
const catchAsync = require("../middlewares/catchAsync");

exports.findAll = catchAsync(async (req, res) => {
  const roles = await Role.findAll();

  return res.status(200).json({
    status: "success",
    data: {
      roles,
    },
  });
});

我不满意的地方

通过上述实现,我在控制台上收到了此错误。

Executing (default): SELECT `id`, `name`, `description`, `createdAt`, `updatedAt` FROM `roles` AS `roles`;
SequelizeDatabaseError: Unknown column 'id' in 'field list'
    at Query.formatError (/home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/dialects/mysql/query.js:239:16)
    at Query.run (/home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/dialects/mysql/query.js:54:18)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async /home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/sequelize.js:619:16
    at async MySQLQueryInterface.select (/home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/dialects/abstract/query-interface.js:938:12)
    at async Function.findAll (/home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/model.js:1741:21)
    at async /home/hello-world/Thesis/SMS-API/src/controllers/roles.js:5:17
    at async /home/hello-world/Thesis/SMS-API/src/middlewares/catchAsync.js:4:7

另一次尝试

我已经如下修改models/role.js

Role.init(
    {
      role_id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER,
      },
      name: DataTypes.STRING,
      description: DataTypes.STRING,
      created_at: DataTypes.DATE,
      updated_at: DataTypes.DATE,
    }

下一次尝试,下一个错误

通过上述修改,我得到了新的错误。

Executing (default): SELECT `role_id`, `name`, `description`, `created_at`, `updated_at`, `createdAt`, `updatedAt` FROM `roles` AS `roles`;
SequelizeDatabaseError: Unknown column 'createdAt' in 'field list'
    at Query.formatError (/home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/dialects/mysql/query.js:239:16)
    at Query.run (/home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/dialects/mysql/query.js:54:18)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async /home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/sequelize.js:619:16
    at async MySQLQueryInterface.select (/home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/dialects/abstract/query-interface.js:938:12)
    at async Function.findAll (/home/hello-world/Thesis/SMS-API/node_modules/sequelize/lib/model.js:1741:21)
    at async /home/hello-world/Thesis/SMS-API/src/controllers/roles.js:5:17
    at async /home/hello-world/Thesis/SMS-API/src/middlewares/catchAsync.js:4:7

帮助

我已经尝试了许多无法解决问题的方法。所以,请帮忙。我想要underscore级别的MySQL级别的MySQL命名约定和“代码”级别的JavaScript命名约定。

非常感谢您。

1 个答案:

答案 0 :(得分:0)

我已经解决了我的问题。现在,我可以针对它们的特定世界使用每种命名约定:under_score用于MySQL,camelCase用于JavaScript。

因此,如果将来有人遇到相同的问题,那么我在这里写了我的解决方案。

我正在使用sequelize-cli创建迁移,模型和种子。您可以检查它here

迁移

迁移仅负责创建/更改/删除表和列。 仅使用数据库访问。

migrations/timestamp-create-role-table.js

"use strict";

module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable("roles", {
      roleId: {
        allowNull: false,
        autoIncrement: true,
        field: "role_id",
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      name: {
        allowNull: false,
        type: Sequelize.STRING(30),
      },
      description: {
        type: Sequelize.STRING(50),
      },
      createdAt: {
        allowNull: false,
        field: "created_at",
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        field: "updated_at",
        type: Sequelize.DATE,
      },
    });
  },

  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable("roles");
  },
};

通过运行以上迁移脚本,我得到了roles表,该表在物理数据库中具有以下各列。 role_id, name, description, created_at, updated_at

种子

Seeder将使用初始测试数据填充表格。我已经按照以下方式填写了roles表。

seeders/timestamp-roles-table-seeder.js

"use strict";

const roles = [
  "official",
  "office",
  "admin"
].map((role) => {
  return {
    name: role,
    created_at: new Date(),
    updated_at: new Date(),
  };
});

module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.bulkInsert("roles", roles);
  },

  down: async (queryInterface, Sequelize) => {
    await queryInterface.bulkDelete("roles", null, {});
  },
};

模型

创建表并填充初始数据后,我需要创建Role模型以便用作MySQL和JavaScript之间的桥梁

models/role.js

"use strict";
const { Model } = require("sequelize");

module.exports = (sequelize, DataTypes) => {
  class Role extends Model {
    static associate(models) {
      // define association here
    }
  }

  Role.init(
    {
      roleId: {
        allowNull: false,
        autoIncrement: true,
        field: "role_id", // SELECT role_id AS id
        primaryKey: true,
        type: DataTypes.INTEGER,
      },
      name: DataTypes.STRING,
      description: DataTypes.STRING,
      createdAt: {
        type: DataTypes.DATE,
        field: "created_at",
      },
      updatedAt: {
        type: DataTypes.DATE,
        field: "updated_at",
      },
    },
    {
      sequelize,
      tableName: "roles",
      modelName: "Role",
    }
  );

  return Role;
};

从JavaScript获取角色

controllers/roles.js

const models = require("../models");
const catchAsync = require("../middlewares/catchAsync");

exports.findAll = catchAsync(async (req, res) => {
  const roles = await models.Role.findAll();

  /*
  you can access 
    - role_id from db with roleId in JS
    - created_at from db with createdAt in JS
  */

  return res.status(200).json({
    status: "success",
    data: {
      roles,
    },
  });
});

希望它会有所帮助!