I'm using sequlize ORM, I have migration file to create associations between tables:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn('testSessions', 'patientId', {
type: Sequelize.UUID,
references: {
model: 'patients',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
});
},
down: async queryInterface => {
await queryInterface.removeColumn('testSessions', 'patientId');
},
};
I want to change onDelete key to 'CASCADE'. Is it possible to write a migration that would change the value of the onDelete attribute?
I don't want to lose the data I have in the table so undoing migration and running is not a solution for me.
Do you know if you can write a migration that will override the onDelete value, how would it look like?
Just write SQL query that removes constraint and then adds constraint using sequelize.query something like below:
var table = 'YOURTABLENAME';
var constraint = 'YOURCONSTRAINTNAME';
var constraintFkey = 'CONSTRAINTFKEY';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query(`alter table "${table}" drop constraint "${constraint}"`)
.then(() => queryInterface.sequelize.query(
`alter table "${table}"
add constraint "${constraint}" foreign key("${constraintFkey}") references "property_service" ("id")
on delete cascade`
));
},
down: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query(`alter table "${tableName}" drop constraint "${constraintName}"`)
.then(() => queryInterface.sequelize.query(
`alter table "${tableName}"\
add constraint "${constraintName}" foreign key("${constraintFkey}") references "patients" ("id")
on delete no action`
));
},
};
Related
I am trying to change an already existing primary key (id) to be changed to autoincrement through Sequelize Migration. Following is what I tried but didnt quite work. I tried removing the constraint, making changes to the column and adding the constraint again.
module.exports = {
up: async (queryInterface, Sequelize) => {
queryInterface.removeConstraint('category', 'category_pkey')
.then(() => {
queryInterface.changeColumn('category', 'id', {
type: Sequelize.DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
}).then(() => {
queryInterface.addConstraint('category', 'category_pkey', {
fields: ['id'],
type: "primary key",
name: 'category_pkey'
});
})
})
},
async down(queryInterface, Sequelize) {
}
};
I am trying to use Sequelize and my brain must have been burnt from the whole project and now I cannot even join tables lol so here we go:
the task is I have two model that creates two tables and another model empty (so an empty table) I would like to join the two table in the third one and after in another statement I would like to count how many users(example) has the first column if there are two user with the same name means that is only one so will count just as one.
module.exports = (sequelize, Sequelize) => {
const Gig = sequelize.define("gig", {
a: {
type: Sequelize.STRING,
},
b: {
type: Sequelize.STRING,
},
c: {
type: Sequelize.STRING,
}
});
return Gig;
};
module.exports = (sequelize, Sequelize) => {
const Gig1 = sequelize.define("gig1", {
a: {
type: Sequelize.STRING,
},
b: {
type: Sequelize.STRING,
},
c: {
type: Sequelize.STRING,
}
});
return Gig1;
};
module.exports = (sequelize, Sequelize) => {
const Gig2 = sequelize.define("gig2", {
a: {
type: Sequelize.STRING,
},
b: {
type: Sequelize.STRING,
},
c: {
type: Sequelize.STRING,
}
});
return Gig2;
};
this is in another file
router.get("/", (req, res) => {
db.Gig.findAll({here the magic should happen thanks guys})
.then((users) => {
console.log(users);
res.sendStatus(200);
})
.catch((err) => {
console.log(err);
});
});
so Gig+Gig1 = Gig2 then count the user in a (so give me the sum without clones)
I found this article written below that is similar to what I am looking for but adding the result to Gig2 that is empty and then do the calcs.
*
UNION ALL and an exclusion join
One way to make UNION include only the duplicates I want is to use an exclusion join to eliminate anything from the second result that is already included in the first, like this:
select * from apples as a
left outer join oranges as o on a.price = o.price
union all
select * from apples as a
right outer join oranges as o on a.price = o.price
where a.price is null;
This handles duplicate rows correctly and doesn’t include anything it shouldn’t. It’s necessary to use UNION ALL instead of plain UNION, which would eliminate the duplicates I want to keep. This may be significantly more efficient on large result sets, since there’s no need to sort and remove duplicates.
I'm using Sequelize in my NodeJS app with Postgres as database. Following is my correct SQL query which gives me right set of data while running them on database server :-
SELECT
"expertises"."uuid" AS "id",
"expertises"."display_name" AS "name",
"expertises"."modified_by" AS "modifiedBy",
(
SELECT COUNT(expertise_uuid)
FROM expertise_endorsements
WHERE expertise_uuid = "expertises"."uuid"
) AS "users"
FROM "expertises" AS "expertises"
LEFT JOIN "expertise_endorsements" AS "expertise_endorsements"
ON "expertise_endorsements"."expertise_uuid" = "expertises"."uuid"
LIMIT '16' OFFSET '1';
However when I run the app, the ORM is generating the wrong SQL query without any count (as shown below):-
SELECT
"expertises".*,
"expertise_endorsements"."id" AS "expertise_endorsements.id",
"expertise_endorsements"."expertise_uuid" AS "expertise_endorsements.expertise_uuid"
FROM
(
SELECT
"expertises"."id",
"expertises"."uuid" AS "id",
"expertises"."display_name" AS "name",
"expertises"."modified_by" AS "modifiedBy",
"expertises"."uuid"
FROM
"expertises" AS "expertises"
ORDER BY
"expertises"."name" DESC LIMIT '16' OFFSET '1'
)
AS "expertises"
LEFT OUTER JOIN
"expertise_endorsements" AS "expertise_endorsements"
ON "expertises"."uuid" = "expertise_endorsements"."expertise_uuid"
ORDER BY
"expertises"."name" DESC;
This is my model association :-
const consts = require("../services/static/constants");
const Expertises = require("./models/expertises.model");
const ExpertisesEndorsees = require("./models/expertises_endorsees.model");
const ExpertisesEndorsements = require("./models/expertise_endorsements.model");
exports.setAssociations = (db, Sequelize, type) => {
const expertisesModel = Expertises(db, Sequelize);
const expertisesEndorseesModel = ExpertisesEndorsees(db, Sequelize);
const expertisesEndorsementsModel = ExpertisesEndorsements(db, Sequelize);
expertisesModel.hasMany(expertisesEndorsementsModel, { sourceKey: consts.uuidField, foreignKey: consts.expertiseUuid, as: consts.modelAliases.EXPERTISE_ENDORSEMENTS });
expertisesEndorsementsModel.belongsTo(expertisesModel, { foreignKey: consts.uuidField, as: consts.modelAliases.EXPERTISE_ENDORSEMENTS });
return { expertisesModel, expertisesEndorseesModel, expertisesEndorsementsModel };
};
My logic is below. I'm stuck in understanding and applying the count properly using the Sequelize:-
const models = dbUtils.setAssociations(db, consts.getExpertiseFlow);
const includesData = [
{
model: models.expertisesEndorsementsModel,
attributes: [consts.expertiseUuid],
// attributes: [
// sequelize.fn("COUNT", sequelize.col(`${consts.modelAliases.EXPERTISE_ENDORSEMENTS}.${consts.get_endorsee_uuid}`)), "users"
// ],
as: consts.modelAliases.EXPERTISE_ENDORSEMENTS,
required: false
}
];
let {count: expertiseCount, rows: expertises} = JSON.parse(JSON.stringify(
await manageExpertise.getSortedExpertises(models, consts.get_expertises, pageOffset, pageLimit, orderBy, includesData, false)));
Method:-
exports.getSortedExpertises = (models, attributes, offset, limit, orderBy, includes, raw=true) => {
return models.expertisesModel
.findAndCountAll({
attributes,
include: includes,
offset: offset,
limit: limit,
//order: orderBy,
raw
}).then(data => {
return data;
})
.catch(err => {
throw err;
});
};
Would really appreciate if you can assist me in resolving this issue and let me know the root cause. Thank you
I am using Sequelize (new to ORM's) and currently have three tables: card and tags, that have a many-to-many relationship that is established with the third table, card_tags. My question is two fold:
How do I seed data across associations?
How do I create new data (i.e. an API function) that establishes new data across associated data bases?
Please see the below for my models and let me know if I'm leaving anything out. Thanks!
cards model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const Card = sequelize.define('card', {
title: {
type: DataTypes.STRING,
allowNull: false
},
link: {
type: DataTypes.STRING,
allowNull: false
}
});
Card.associate = (models) => {
Card.belongsToMany(models.tag, { through: 'card_tag', as: 'tag' });
};
return Card;
};
tags model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const Tag = sequelize.define('tag', {
title: {
type: DataTypes.STRING,
allowNull: false
}
});
Tag.associate = (models) => {
Tag.belongsToMany(models.card, { through: 'card_tag', as: 'card'});
};
return Tag;
};
card_tags model:
'use strict';
module.exports = function(sequelize, DataTypes) {
const CardTag = sequelize.define('card_tag', {
cardId: DataTypes.INTEGER,
tagId: DataTypes.INTEGER
});
return CardTag;
};
The simplest and quickest way to do is to to insert bulk data in each relation.
You can write sequelize queries to bulkInsert keeping in mind that primary key for each foriegn key is created first.
You can use faker npm module to generate random data.
I have a feathers api set up using feathers-sequelize to persist to a MySQL database.
I've got the datamodel set up and can see the relevant tables are created.
const Sequelize = require('sequelize');
module.exports = function (app) {
const sequelizeClient = app.get('sequelizeClient');
const orders = sequelizeClient.define('orders', {
id: {
type: Sequelize.UUID,
primaryKey: true,
defaultValue: Sequelize.UUIDV4
}, {
classMethods: {
associate (models) {
this.belongsToMany(models.users, {through: "offers", foreignKey: "orderId", otherKey: "userId"});
}
}
});
return orders;
};
How do I actually create an association of offers? I've tried something like this:
const orders = hook.app.service("orders");
order.offers.push(user.id);
orders.patch(order.id, order);
but it doesn't seem to have any effect
You shouldn't need to patch with a many-to-many. Simply use the Sequelize association method:
order.addUser(user.id)
To return the association you might need to do an order.reaload() in your after hook.