Sequelize - 模型和迁移
Posted
技术标签:
【中文标题】Sequelize - 模型和迁移【英文标题】:Sequelize - Model and Migrations 【发布时间】:2020-11-09 02:14:57 【问题描述】:[已解决!]
我在互联网上进行了很多研究,并发现了一些与我类似的问题。但是,我找不到解决问题的正确方法。请帮忙。
我正在使用 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
帮助
我尝试了很多方法都无法解决我的问题。所以,请帮忙。我想要 MySQL 级别的 MySQL 命名约定 underscore
和代码级别的 javascript 命名约定。
非常感谢。
【问题讨论】:
【参考方案1】:我已经解决了我的问题。我现在可以为他们的特定世界使用每个命名约定:under_score
用于 MySQL,camelCase
用于 JavaScript。
因此,如果将来有人遇到同样的问题,我会在这里写下我的解决方案。
我正在使用sequelize-cli
创建迁移、模型和播种机。您可以查看here。
迁移
Migration 只负责创建/更改/删除表和列。 它只访问数据库。
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,
,
);
);
希望对您有所帮助!
【讨论】:
以上是关于Sequelize - 模型和迁移的主要内容,如果未能解决你的问题,请参考以下文章
使用随时间变化的模型为 Sequelize 制作可重现的迁移字符串?