Reputation: 476
[Resolved !]
I've researched a lot on the Internet and found some similar question with mine. But, I can't find the proper way to fix my problem. Please help.
I'm using Sequelize v6. I've some troubles in using models and migrations.
What I've done:
I generated role model using sequelize cli. And it gives me below code in 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;
};
And I also got migration file for that model in 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");
},
};
What I got in MySQL
By running the above migration, I got roles
table with following columns:
role_id, name, created_at, updated_at
which is fine. That is what I want in MySQL database.
Reading roles
/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,
},
});
});
What I'm not OK
With the above implementation, I got this error on the console.
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
Another Attempt
I've modified models/role.js
like below.
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,
}
Next try, Next Error
With the above modification, I got new error.
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
HELP
I've tried so many ways which cannot fix my problem yet. So, please help. I want MySQL naming convention in MySQL level which is underscore
and JavaScript naming convention in Code level.
Thank you so much.
Upvotes: 2
Views: 3699
Reputation: 476
I've fixed my problem. I can now use each naming convention for their specific world: under_score
for MySQL and camelCase
for JavaScript.
So here I've written my solution if someone come across the same issue in the future.
I'm using sequelize-cli
for creating migrations, models and seeders. You can check it here.
Migration
Migration is only responsible for creating/altering/deleting the tables and columns. It access with only the database.
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");
},
};
By running the above migration script, I got the roles
table with following columns in my physical database.
role_id, name, description, created_at, updated_at
Seeder
Seeder will populate your table with initial test data. I've filled my roles
table like below.
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, {});
},
};
Model
After I've created table and filled up with initial data, I need to create Role
model in order to use as bridge between MySQL and 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;
};
Getting roles from 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,
},
});
});
Hope it could help!
Upvotes: 2