Sequelizejs not giving clean data - express

When I query my database through sequelize.js using the following query:
models.User.findAll({
attributes: ['name', 'company_id'],
where: {
id: 6
}
}).then( function( data ) {
console.log( data );
});
I get :
[ { dataValues: { name: 'John', company_id: 221 },
_previousDataValues: { name: 'John', company_id: 221 },
_changed: {},
'$modelOptions':
{ timestamps: true,
instanceMethods: {},
classMethods: {},
validate: {},
freezeTableName: false,
underscored: false,
underscoredAll: false,
paranoid: false,
whereCollection: [Object],
schema: null,
schemaDelimiter: '',
defaultScope: null,
scopes: [],
hooks: {},
indexes: [],
name: [Object],
tableName: 'users',
createdAt: 'created',
updatedAt: 'modified',
omitNull: false,
sequelize: [Object],
uniqueKeys: {},
hasPrimaryKeys: true },
'$options': { isNewRecord: false, raw: true, attributes: [Object] },
hasPrimaryKeys: true,
__eagerlyLoadedAssociations: [],
isNewRecord: false } ]
How do I configure sequelize to give me clean data,i.e., only data rows and nothing else.

Related

Sequelize how to add distinct and exclude field from group in .findAll()?

I have working query:
const counter = await models.CompanyProductionUnitNonCeased
.findAll({
raw: true,
attributes: [
'production_unit.production_unit_renteds.address.geograpical_administrative_areas.region_code_region.name',
'production_unit.production_unit_renteds.address.geograpical_administrative_areas.region_code_region.code',
// [sequelize.literal('DISTINCT `company_id`'), 'company_id', 'company_id'],
[sequelize.fn('COUNT', 'production_unit.production_unit_renteds.address.geograpical_administrative_areas.region_code_region.code'), 'total']
],
group: ['production_unit.production_unit_renteds.address.geograpical_administrative_areas.region_code_region.name', 'production_unit.production_unit_renteds.address.geograpical_administrative_areas.region_code_region.code'],
include: [{
attributes: [],
required: true,
model: models.ProductionUnitCore,
as: "production_unit",
include: [{
attributes: [],
required: true,
model: models.ProductionUnitRented,
as: 'production_unit_renteds',
where: { is_current: true },
include: [{
attributes: [],
required: true,
model: models.AddressAddress,
as: 'address',
include: [{
attributes: [],
required: true,
model: models.GeograpicalAdministrativeAreas,
as: 'geograpical_administrative_areas',
include: [{
required: true,
model: models.Region,
as: 'region_code_region',
attributes: [],
where: {}
}],
}]
}]
}]
}]
})
The result is:
[
{ name: 'Region Sjælland', code: 1085, total: 132696 },
{ name: 'Region Hovedstaden', code: 1084, total: 362711 },
{ name: 'Region Syddanmark', code: 1083, total: 189661 },
{ name: 'Region Midtjylland', code: 1082, total: 224464 },
{ name: 'Region Nordjylland', code: 1081, total: 94023 }
]
How can I add distinct by "company_id" for model "CompanyProductionUnitNonCeased" key to not add this key into "group", so in total column should be less values (only unique)?
Solution:
It just need to add into attributes, where table name is class name of the table :)
[sequelize.literal(`count(DISTINCT(CompanyProductionUnitNonCeased.company_id))`), 'count']
Here is full solution:
const count = await models.CompanyProductionUnitNonCeased
.findAll({
raw: true,
attributes: [
[sequelize.literal(`count(DISTINCT(CompanyProductionUnitNonCeased.company_id))`), 'count'],
`production_unit.production_unit_renteds.address.geograpical_administrative_areas.${stringByGroup}.name`,
`production_unit.production_unit_renteds.address.geograpical_administrative_areas.${stringByGroup}.code`,
],
group: [
`production_unit.production_unit_renteds.address.geograpical_administrative_areas.${stringByGroup}.name`,
`production_unit.production_unit_renteds.address.geograpical_administrative_areas.${stringByGroup}.code`],
where: { ...whereBy },
include: [{
attributes: [],
required: true,
model: models.ProductionUnitCore,
as: "production_unit",
include: [{
attributes: [],
required: true,
model: models.ProductionUnitRented,
as: 'production_unit_renteds',
where: { is_current: true },
include: [{
attributes: [],
required: true,
model: models.AddressAddress,
as: 'address',
include: [{
attributes: [],
required: true,
model: models.GeograpicalAdministrativeAreas,
as: 'geograpical_administrative_areas',
include: [{
required: true,
model: models.Region,
as: 'region_code_region',
attributes: []
}]
}]
}]
}]
}]
})

How to substitute an array from my Table? Sequelize

I've the following table:
User.init({
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false
},
purchased_book: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: false,
},
surname: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
timestamps: false,
sequelize: sequelizeConnection,
paranoid: true
})
I want to remove only one item from the purchased_book array. purchased_book is an array of book:
export interface book{
title: string;
author: string;
price: number;
id: number | undefined;
}
How can I access to the field User.purchased_book.id? I've tried with:
async function remove_book_from_user_array(user_id: number, book_id: number){
var new_array: book[] = User.purchased_book;
await User.update({purchased_book: new_array}, {
where: {
id: user_id
}
})
}

Sequelize select with two relations to the same entity

I have 2 tables, ItemLegacy :
module.exports = function(sequelize, DataTypes) {
return sequelize.define('ItemLegacy', {
id: {
type: DataTypes.INTEGER(11).UNSIGNED,
allowNull: false,
primaryKey: true
},
parent: {
type: DataTypes.INTEGER(11),
allowNull: false,
defaultValue: 0,
},
child: {
type: DataTypes.INTEGER(11),
allowNull: false,
defaultValue: 0
}
}, {
tableName: 'ItemLegacy',
timestamps: false,
underscored: false
});
};
and Item :
module.exports = function(sequelize, DataTypes) {
return sequelize.define('Item', {
id: {
type: DataTypes.INTEGER(11).UNSIGNED,
allowNull: false,
primaryKey: true
},
title: {
type: DataTypes.STRING(500),
allowNull: false,
defaultValue: ''
},
code: {
type: DataTypes.STRING(20),
allowNull: true
},
}, {
tableName: 'Item',
timestamps: false,
underscored: false
});
};
I also defined two relationships :
db.ccnLegacy.hasOne(db.ccn, { foreignKey: 'id', sourceKey: 'parent' })
db.ccnLegacy.hasOne(db.ccn, { foreignKey: 'id', sourceKey: 'child' })
My question is, I would like to create a select request using sequelize, with a relation for each of the 2 fields parent and child.
I know how to do that with one relation, but how do I do it with 2 ?
My code with only one relation :
db.itemLegacy.findOne({
raw: true,
where: { child: idChild },
include: [
{
model: db.item
},
]
})
You simply should indicate aliases for both associations and use them in queries. Second is you used hasOne instead of belongTo because belongTo is used exactly in a case when you go from N to 1 in N:1 relationship.
Associations:
db.ccnLegacy.belongsTo(db.ccn, { foreignKey: 'parent', as: 'Parent' })
db.ccnLegacy.belongsTo(db.ccn, { foreignKey: 'child', as: 'Child' })
Query:
db.itemLegacy.findOne({
raw: true,
where: { child: idChild },
include: [
{
model: db.item,
as: 'Child'
},
{
model: db.item,
as: 'Parent'
},
]
})

Load attributes from associated model in sequelize.js

I have two models. User and Manager
User Model
const UserMaster = sequelize.define('User', {
UserId: {
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
RelationshipId: {
type: DataTypes.STRING,
allowNull: true,
foreignKey: true
},
UserName: {
type: DataTypes.STRING,
allowNull: true
}
})
Manager model
const Manager = sequelize.define('Manager', {
ManagerId: {
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
RelationshipId: {
type: DataTypes.STRING,
allowNull: true,
foreignKey: true
},
MangerName: {
type: DataTypes.STRING,
allowNull: true
}
})
Models are minified to simplyfy the problem
Associations..
User.belongsTo(models.Manager, {
foreignKey: 'RelationshipId',
as: 'RM'
});
Manger.hasMany(model.User, {
foreignKey: 'RelationshipId',
as: "Users"
})
So, on user.findAll()
var userObject = models.User.findAll({
include: [{
model: models.Manager,
required: false,
as: 'RM',
attributes: ['ManagerName']
}]
});
I get the following.
userObject = [{
UserId: 1,
RelationshipId: 4545,
UserName: 'Jon',
RM: {
ManagerName: 'Sam'
}
},
{
UserId: 2,
RelationshipId: 432,
UserName: 'Jack',
RM: {
ManagerName: 'Phil'
}
},
...
]
How can I move 'ManagerName' attribute from Manager model (associated as RM) to UserObject?
Is it possible to somehow load attributes from eagerly-loaded models without nesting them under a separate object?
I expected the resulting Object to look Like the object
Expected Object --
userObject = [{
UserId: 1,
RelationshipId: 4545,
UserName: 'Jon',
ManagerName: 'Sam' // <-- from Manager model
},
{
UserId: 2,
RelationshipId: 432,
UserName: 'Jack',
ManagerName: 'Phil' // <-- from Manager model
},
...
]
Thank you.
Adding raw: true along with attributes option worked to get the desired object format.
So,
var userObject = models.User.findAll({
raw:true,
attributes: {
include: [Sequelize.col('RM.ManagerName'), 'ManagerName']
},
include: [{
model: models.Manager,
required: false,
as: 'RM',
attributes: []
}]
});

How to populate data from jqGrid row to a textbox

I have a main jqgrid working with 5 columns out of 22 columns. I want to populate the 22 columns data in toolboxes (textbox, checkbox...) when a row is selected
Using a jqgrid subgrid all work perfectly.
So how to populate the data passed into the subgrid to my toolbox elements instead.
The other work arround that works, but does not satisfy me, is to call all needed data in the main grid hide the 22 columns and populate them in the boxes onselect. See whole code below:
jQuery(document).ready(function () {
$("#grid").jqGrid({
url: 'GetDemandeurs_Cons',
datatype: 'json',
mtype: 'GET',
colNames: [
'Code',
'Nom',
'Prenoms',
'Courriel',
'Adresse_Demandeur',
],
colModel: [
{ key: true, name: 'Code_Demandeur', index: 'Code_Demandeur' },
{ key: false, name: 'Nom_Demandeur', index: 'Nom_Demandeur' },
{ key: false, name: 'Prenoms_Demandeur', index: 'Prenoms_Demandeur' },
{ key: false, name: 'Courriel1_Demandeur', index: 'Courriel1_Demandeur' },
{ key: false, name: 'Adresse_Demandeur', index: 'Adresse_Demandeur' },
],
pager: $('#pager'),
rowNum: 10,
rowList: [5, 10, 20, 50],
height: '100%',
emptyrecords: "Pas d'enregistrement à afficher",
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
id: "0"
},
autowidth: true,
multiselect: false,
sortname: 'Code_Demandeur',
sortorder: "asc",
viewrecords: true,
//caption: '<bListe des demandeurs</b>',
onSelectRow: function (ids) {
var data = $("#grid").getRowData(ids);
if (ids != null) {
console.log(data.Code_Demandeur);
console.log(data.Adresse_Demandeur);
$("#detailsDdeur")
.setGridParam({ url: "GetDdeurs_Cons_Subgrid?id=" + data.Code_Demandeur, page: 1 })
.setCaption("<b>Details pour : " + data.Prenoms_Demandeur + ' ' + data.Nom_Demandeur + "</b>")
.trigger('reloadGrid');
}
}
}).navGrid(pager, { edit: false, add: false, del: false, refresh: true, search: false });
jQuery("#grid").jqGrid('hideCol', ["Adresse_Demandeur"]);
$("#detailsDdeur").jqGrid
({
height: 100,
datatype: "json",
colNames: [
'Adresse_Demandeur',
'Ville',
'Province',
'Code Postal',
'Téléphone',
'Tel2_Demandeur',
'Tel3_Demandeur',
'Courriel2_Demandeur',
'Courriel3_Demandeur',
'ID_SituationMatrimoniale',
'Sexe',
'Date de Naissance',
'Revenu_Demandeur',
'ID_Occupation',
'ID_Scolarite',
'ID_StatutLegal',
'ID_Communaute',
'ID_SourceInformation',
'Handicape',
'Reference',
'Remarques_Demandeur',
'Photo'
],
colModel:
[
{ key: false, name: 'Adresse_Demandeur', index: 'Adresse_Demandeur' },
{ key: false, name: 'Ville', index: 'Ville' },
{ key: false, name: 'Province', index: 'Province' },
{ key: false, name: 'CodePostal_Demandeur', index: 'CodePostal_Demandeur' },
{ key: false, name: 'Tel1_Demandeur', index: 'Tel1_Demandeur' },
{ key: false, name: 'Tel2_Demandeur', index: 'Tel2_Demandeur' },
{ key: false, name: 'Tel3_Demandeur', index: 'Tel3_Demandeur' },
{ key: false, name: 'Courriel2_Demandeur', index: 'Courriel2_Demandeur' },
{ key: false, name: 'Courriel3_Demandeur', index: 'Courriel3_Demandeur' },
{ key: false, name: 'SitMat', index: 'SitMat' },
{ key: false, name: 'Sexe', index: 'Sexe' },
{ key: false, name: 'Date_Naissance_Demandeur', index: 'Date_Naissance_Demandeur' },
{ key: false, name: 'Revenu_Demandeur', index: 'Revenu_Demandeur' },
{ key: false, name: 'Occupation', index: 'Occupation' },
{ key: false, name: 'Scolarite', index: 'Scolarite' },
{ key: false, name: 'StatutLegal', index: 'StatutLegal' },
{ key: false, name: 'Communaute', index: 'Communaute' },
{ key: false, name: 'SourceInformation', index: 'SourceInformation' },
{ key: false, name: 'Handicape', index: 'Handicape' },
{ key: false, name: 'Reference', index: 'Reference' },
{ key: false, name: 'Remarques_Demandeur', index: 'Remarques_Demandeur' },
{ key: false, name: 'ID_Photo', index: 'ID_Photo' }
],
rowNum: 5,
rowList: [5, 10, 20],
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
id: "0"
},
viewrecords: true,
sortorder: "desc",
}).navGrid('#OrderPager', { add: false, edit: false, del: false, search: false });
});
Add Code as given Below
colModel: [
{ name: 'Code_Demandeur', index: 'Code_Demandeur', width: 15, sorttype: "int", sortable: false, resizable: false,
formatter: function (cellvalue, options, rowObject) {
TxtRankName = "Code_Demandeur_" + options.rowId;
return txtBx(TxtRankName, cellvalue)
}
}
]
function txtBx(Id, Value) {
strTextBox = "<input type='text' id='" + Id + "'";
if (Value != "")
strTextBox = strTextBox + " title='" + Value + "' value='" + Value + "'";
strTextBox = strTextBox + " />";
return strTextBox;
}