Creating table from sequelize-auto with init-mode.js and js files - javascript

I made init-models.js, testtbl.js and usertbl.js with sequelize-auto in ubuntu from mysql table structure.
Command I executed in ubuntu shell:
$ sequelize-auto -o "./models" -h localhost -u foo -p bar -x password -e mysql
And I saw that Sequelize-auto made files models/init.js and models/testtbl.js, usertbl.js
Unfortunately, I blew up mysql table testtbl, usertbl entirely and I want to recover it with testtbl.js and usertbl.js
I want to know sequelize command that making table testtbl and usertbl on mysql with models/init-models.js, models/testtb.js and usertbl.js
I can show init-model.js, testtbl.js and usertbl.js
init-model.js :
var DataTypes = require("sequelize").DataTypes;
var _testtbl = require("./testtbl");
var _usertbl = require("./usertbl");
function initModels(sequelize) {
var testtbl = _testtbl(sequelize, DataTypes);
var usertbl = _usertbl(sequelize, DataTypes);
return {
testtbl,
usertbl
};
}
module.exports = initModels;
module.exports.initModels = initModels;
module.exports.default = initModels;
testtbl.js :
const Sequelize = require('sequelize');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('testtbl', {
idx: {
autoIncrement: true,
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true
},
val: {
type: DataTypes.STRING(45),
allowNull: true
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}, {
sequelize,
tableName: 'testtbl',
timestamps: false,
indexes: [
{
name: "PRIMARY",
unique: true,
using: "BTREE",
fields: [
{ name: "idx" },
]
},
]
});
};
usertbl.js :
const Sequelize = require('sequelize');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('usertbl', {
uididx: {
autoIncrement: true,
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true
},
uid: {
type: DataTypes.STRING(45),
allowNull: false,
unique: "uid_UNIQUE"
},
passwd: {
type: DataTypes.STRING(45),
allowNull: true
},
devicename: {
type: DataTypes.STRING(45),
allowNull: true
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}, {
sequelize,
tableName: 'usertbl',
timestamps: false,
indexes: [
{
name: "PRIMARY",
unique: true,
using: "BTREE",
fields: [
{ name: "uididx" },
]
},
{
name: "uid_UNIQUE",
unique: true,
using: "BTREE",
fields: [
{ name: "uid" },
]
},
]
});
};

Related

Sequlize How to make bulkCreate with associated table and not create new values if theay already exist in table

I Have 2 models. Actors And Movies, they have BelongsToMany Asscociation
const Movie = sequelize.define(
MOVIES,
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
title: {
type: DataTypes.STRING,
allowNull: false,
},
year: {
type: DataTypes.NUMBER,
allowNull: false,
},
format: {
type: DataTypes.ENUM,
values: [VHS, DVD, BLU_RAY],
allowNull: false,
},
},
{
indexes: [
{
unique: true,
fields: ['title'],
},
],
}
);
const Actor = sequelize.define(
ACTORS,
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
indexes: [
{
unique: true,
fields: ['name'],
},
],
}
);
and this logic:
const moviesData = req.files.movies.data.toString();
const newMovies = movieHelper.formatArrayOfMovieObjects(moviesData);
const movies = await Movie.bulkCreate(newMovies, {
include: {
model: Actor,
},
updateOnDuplicate: ['title'],
});
res.json(movies).status(200);
How to make to not create new records if movie.title exist in table
I tried updateOnDuplicate param but it give me this error: [Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed
If your SQLite version supports unique constraints/indexes then you can create one indicating the title field and this way the option updateOnDuplicate should work well.

How to do a query in Sequelize?

I've an existing Postgres database. Throught sequelize-auto, I generated the models for the existing database. For example, let's look at the tc_devices table (tc_devices.js):
const Sequelize = require('sequelize');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('tc_devices', {
id: {
autoIncrement: true,
autoIncrementIdentity: true,
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING(128),
allowNull: false
},
uniqueid: {
type: DataTypes.STRING(128),
allowNull: false,
unique: "tc_devices_uniqueid_key"
},
lastupdate: {
type: DataTypes.DATE,
allowNull: true
},
positionid: {
type: DataTypes.INTEGER,
allowNull: true
},
groupid: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: 'tc_groups',
key: 'id'
}
},
attributes: {
type: DataTypes.STRING(4000),
allowNull: true
},
phone: {
type: DataTypes.STRING(128),
allowNull: true
},
model: {
type: DataTypes.STRING(128),
allowNull: true
},
contact: {
type: DataTypes.STRING(512),
allowNull: true
},
category: {
type: DataTypes.STRING(128),
allowNull: true
},
disabled: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: false
}
}, {
sequelize,
tableName: 'tc_devices',
schema: 'public',
timestamps: false,
indexes: [
{
name: "tc_devices_pkey",
unique: true,
fields: [
{ name: "id" },
]
},
{
name: "tc_devices_uniqueid_key",
unique: true,
fields: [
{ name: "uniqueid" },
]
},
]
});
};
In database.js, I connect to the database:
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize(database, user, password, {
host,
port,
dialect: 'postgres',
logging: false
})
async function db_connection(){
try{
await sequelize.authenticate();
console.log('Connection has been estabilished successfully.');
}catch{
console.log('Unable to connect to the database.');
}
}
db_connection()
How can I do a simple query on the tc_devices table? what should I import in database.js? in tc_devices I export function(sequelize, DataTypes)... but I can't understand how to do a query in database.js with this function...could you help me? thank you so much.
You need to register all models and their associations before executing the first query with these models. Look at my answer here.
As soon as you do it you can execute queries like this:
// assuming db already stores all model definitions
const allRecords = await db.tcDevices.findAll({})

How can I parse complex query operations using Sequelize.js?

I have an Option table which has a question_id as a foreign key to table Questions.
Then in Questions table I've 2 foreign keys namely question_category_id and section_id. For the 1st Option part I am able to apply LEFT OUTER JOIN query but also I need to fetch the values of Question_Category and Section table as well.
Let me first clear out how I want my output to be:
Output JSON
"questions": [
{
"id": 9,
"isActive": true,
"question_text": "What is abc ?",
"createdBy": "avis",
"questionCategory": {
"id": 1,
"name": "aptitude"
},
"section": {
"id": 1,
"marks": 5
},
"options": [
{
"id": 1,
"answer": true,
"option_text": "A",
"question_id": 9
},
{
"id": 2,
"answer": false,
"option_text": "B",
"question_id": 9
}
]
}
]
Now I am specifying my database models:
question_category.js
module.exports = (sequelize, Sequelize) => {
const QuestionCategory = sequelize.define('question_category', {
id:{ type: Sequelize.BIGINT, autoIncrement: true, allowNull: false, primaryKey: true },
isActive: { type: Sequelize.BOOLEAN, allowNull: false },
question_category_name: { type: Sequelize.STRING, allowNull: false },
createdBy: { type: Sequelize.STRING, allowNull: false },
createdAt: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }
}, { timestamps: false });
return QuestionCategory;
};
section.js
module.exports = (sequelize, Sequelize) => {
const Section = sequelize.define('section', {
id: { type: Sequelize.BIGINT, autoIncrement: true, allowNull: false, primaryKey: true },
isActive: { type: Sequelize.BOOLEAN, allowNull: false },
marks_per_question: { type: Sequelize.INTEGER, allowNull: false },
createdBy: { type: Sequelize.STRING, allowNull: false },
createdAt: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }
}, { timestamps: false });
return Section;
};
question.js
module.exports = (sequelize, Sequelize) => {
const Questions = sequelize.define('questions', {
id:{ type: Sequelize.BIGINT, autoIncrement: true, allowNull: false, primaryKey: true },
isActive: { type: Sequelize.BOOLEAN, allowNull: false },
question_text: { type: Sequelize.STRING, allowNull: false },
createdBy: { type: Sequelize.STRING, allowNull: false },
createdAt: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }
}, { timestamps: false });
return Questions;
};
option.js
module.exports = (sequelize, Sequelize) => {
const Options = sequelize.define('options', {
id:{ type: Sequelize.BIGINT, autoIncrement: true, allowNull: false, primaryKey: true },
answer: { type: Sequelize.BOOLEAN, allowNull: true },
option_text: { type: Sequelize.STRING, allowNull: false },
createdAt: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }
}, { timestamps: false });
return Options;
};
In the database.js i.e. the main js file for exporting the models I have associated the models like this:
const dbConfig = require('../config/db.config');
const Sequelize = require('sequelize');
const sequelize = new Sequelize(
dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD,
{
host: dbConfig.HOST,
port: dbConfig.PORT,
dialect: 'mysql',
operatorsAliases: 0
}
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch(err => {
console.error('Unable to connect to the database:', err);
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.QuestionCategory = require('./question_model/question_category')(sequelize, Sequelize);
db.Section = require('./question_model/section')(sequelize, Sequelize);
db.Question = require('./question_model/question')(sequelize, Sequelize);
db.Option = require('./question_model/option')(sequelize, Sequelize);
// Relating Question Category with Questions
db.QuestionCategory.hasMany(db.Question, {
foreignKey: 'question_category_id',
sourceKey: 'id'
});
db.Question.belongsTo(db.QuestionCategory, {
foreignKey: 'question_category_id',
targetKey: 'id'
});
// Relating Sections with Questions
db.Section.hasMany(db.Question, {
foreignKey: 'section_id',
sourceKey: 'id'
});
db.Question.belongsTo(db.Section, {
foreignKey: 'section_id',
targetKey: 'id'
});
// Relating Questions with Options
db.Question.hasMany(db.Option, {
foreignKey: 'question_id',
sourceKey: 'id'
});
db.Option.belongsTo(db.Question, {
foreignKey: 'question_id',
targetKey: 'id'
});
So this is my structure.
Now to achieve the above output format I've written the below logic but it's not outputting the correct JSON:
const db = require('../models/database');
const errors = require('../config/errors').errors;
exports.viewQuestion = (req, res, next) => {
try {
db.Question.findAll({
attributes: { exclude: ['createdAt','section_id','question_category_id'] },
include: [{
model: db.Option,
attributes: { exclude: ['createdAt'] }
}]
}).then(data => {
if(data.length == 0) {
return res.status(200).send({
status: 200,
questions: 'No Data'
});
}
db.QuestionCategory.findAll({
attributes: { exclude: ['createdBy','createdAt','isActive'] },
include: db.Question,
attributes: { exclude: ['id','isActive','question_text','createdBy','createdAt','section_id'] }
}).then(question_category => {
Object.assign(data[0], { 'questionCategories': question_category });
res.status(200).send({
status: 200,
questions: data
});
});
}).catch(err => {
return res.status(204).send(errors.MANDATORY_FIELDS);
});
} catch(err) {
return res.status(204).send(errors.MANDATORY_FIELDS);
}
};
I didn't wrote the logic for Section part yet as I was going Step by Step. The output that I am getting by writing this logic is:
{
"status": 200,
"questions": [
{
"id": 9,
"isActive": true,
"question_text": "What is abc ?",
"createdBy": "avis",
"options": [
{
"id": 1,
"answer": true,
"option_text": "A",
"question_id": 9
},
{
"id": 2,
"answer": false,
"option_text": "B",
"question_id": 9
}
]
}
]
}
The questionCategories didn't got reflected in the output.
Please help me out as I've more scenarios like this and all I can solve depending on this.
If you are using Sequelize to get objects from a DB via models then you should turn them into plain objects before adding some properties. For instance, if you get a collection of objects you should call get({ plain: true }) for each of them.
const plainObj = data[0].get({ plain: true })
Object.assign(plainObj, { 'questionCategories': question_category });
res.status(200).send({
status: 200,
questions: plainObj
});

Sequelize - foreign key on create include returns null

The foreign key returns null when inserted using create include, but the rest of data is saved from the passed object.
Here is my transaction model:
module.exports = (sequelize, DataTypes) => {
const Transaction = sequelize.define('transactions', {
id: {
type: DataTypes.INTEGER,
allowNull: true,
primaryKey: true
},
receiptNumber: {
type: DataTypes.TEXT,
allowNull: true
},
supCustID: {
type: DataTypes.INTEGER,
allowNull: true
},
userID: {
type: DataTypes.INTEGER,
allowNull: true
},
type: {
type: DataTypes.TEXT,
allowNull: true
},
status: {
type: DataTypes.INTEGER,
allowNull: true
},
remarks: {
type: DataTypes.TEXT,
allowNull: true
},
createdAt: {
type: 'TIMESTAMP',
defaultValue: sequelize.literal('CURRENT_TIMESTAMP'),
allowNull: false
},
updatedAt: {
type: 'TIMESTAMP',
defaultValue: sequelize.literal('CURRENT_TIMESTAMP'),
allowNull: false
}
}, {
tableName: 'transactions'
});
Transaction.associate = models => {
Transaction.Order = Transaction.hasMany(models.Order, {
as: 'Orders',
foreignKey: 'transaction_id'
})
Transaction.SupCust = Transaction.belongsTo(models.SupCust, {
as: 'SupCust',
foreginKey: 'supCustID'
})
Transaction.User = Transaction.belongsTo(models.User, {
as: 'User',
foreginKey: 'userID'
})
}
return Transaction;
};
Orders Model:
/* jshint indent: 1 */
module.exports = (sequelize, DataTypes) => {
const Order = sequelize.define('orders', {
id: {
type: DataTypes.INTEGER,
allowNull: true,
primaryKey: true
},
transaction_id: {
type: DataTypes.INTEGER,
allowNull: true
},
itemID: {
type: DataTypes.TEXT,
allowNull: true
},
qty: {
type: DataTypes.INTEGER,
allowNull: true
},
itemCost: {
type: DataTypes.REAL,
allowNull: true
},
discount: {
type: DataTypes.REAL,
allowNull: true
},
totalAmount: {
type: DataTypes.REAL,
allowNull: true
}
}, {
tableName: 'orders',
timestamps: false,
hooks: {
afterValidate: (Order) => {
console.log(Order)
},
}
});
Order.associate = models => {
Order.belongsTo(models.Transaction, {
as: 'Transactions',
foreignKey: 'transaction_id'
})
Order.belongsTo(models.ItemList, {
as: 'Items',
foreignKey: 'itemID'
})
}
return Order;
};
Code to execute insert data:
return await models.Transaction
.findOne({ where: { id: values.id || -1 } })
.then(async function (obj) {
if(obj) { // update
return await obj.update(values, {individualHooks: true});
}
else { // insert
const {id, ...payload} = values
return await models.Transaction.create(payload, {
include: [{
association: models.Transaction.Order
}],
});
}
})
Results from console:
Executing (default): INSERT INTO `transactions` (`id`,`receiptNumber`,`supCustID`,`userID`,`type`,`createdAt`,`updatedAt`) VALUES ($1,$2,$3,$4,$5,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);
Executing (default): INSERT INTO `orders` (`id`,`transaction_id`,`itemID`,`qty`,`itemCost`) VALUES ($1,$2,$3,$4,$5);
Console log from hooks on orders model:
dataValues:
{ id: null,
itemID: 1008,
itemCost: '2',
qty: '1',
transaction_id: null },
Why is this always null? what am i missing something?
Solved this by adding autoincrement property on my transaction model.
id: {
type: DataTypes.INTEGER,
allowNull: true,
primaryKey: true,
autoIncrement: true
}

Sequelize bulkCreate not including newly added columns

I'm having difficulty understanding why bulkCreate will not include my two newly created columns, perhaps it's the migration?
My new migration is as follows:
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
queryInterface.addColumn('users', 'brand_id', {
allowNull: true,
type: Sequelize.INTEGER,
defaultValue: null,
});
queryInterface.addColumn('users', 'store_id', {
allowNull: true,
type: Sequelize.INTEGER,
defaultValue: null,
});
return true;
},
down: (queryInterface, Sequelize) => {
queryInterface.removeColumn('users', 'brand_id');
queryInterface.removeColumn('users', 'store_id');
return true;
}
};
I have a helper function for creating multiple users for the purpose of testing that looks something like this:
const properties = { brand_id: 123 };
const user = [];
users.push(Object.assign({}, {
name: chance.last(),
email: chance.email(),
password,
access_key: uuid(),
}, properties));
const newUsers = await models.user.bulkCreate(users, { returning: true, logging: console.log });
The output of the logging is:
INSERT INTO "users" ("id","name","email","password","access_key","created_at","updated_at") VALUES (DEFAULT,'Valente','letubdo#iwefa.fm','$2a$08$B5riQzA82ChwuH1q8HpGxOBK2uQj2m.BiHcEjytiox5yD.8u1fT5W','e62bf96c-0117-490f-9c80-b60e406238b0','2018-09-25 18:30:04.666 +00:00','2018-09-25 18:30:04.666 +00:00') RETURNING *;
You'll see that brand_id is completely ignored in the query, even if I change the following:
users.push(Object.assign({}, {
name: chance.last(),
email: chance.email(),
password,
access_key: uuid(),
brand_id: 123,
}, properties));
Any idea what could be wrong?
It turns out I did not add the two new columns to the user model:
'use strict';
module.exports = (sequelize, DataTypes) => {
var user = sequelize.define('user', {
name: {
allowNull: false,
type: DataTypes.STRING
},
email: {
allowNull: false,
type: DataTypes.STRING
},
password: {
allowNull: false,
type: DataTypes.STRING
},
access_key: {
allowNull: false,
type: DataTypes.STRING
},
brand_id: {
allowNull: true,
true: DataTypes.INTEGER,
},
store_id: {
allowNull: true,
true: DataTypes.INTEGER,
}
}, {
underscored: true,
});
return user;
};

Categories

Resources