I have a given database with long, cumbersome columnnames. Isn't there any way to map the tablenames to shorter and more descriptive propertyNames in the model ?
something like
var Employee = sql.define('Employee', {
id : {type : Sequelize.INTEGER , primaryKey: true, map : "veryLongNameForJustTheId"}
},{
tableName: 'cumbersomeTableName',
timestamps: false
});;
id : {
field: 'some_long_name_that_is_terrible_thanks_dba_guy',
type : Sequelize.INTEGER ,
primaryKey: true
}
Specify a 'field' attribute ... Like that ^
You can specify a table name by supplying the name as the first parameter to the define() call. For example:
var User = sequelize.define(
'a_long_cumbersone_users_table_name',
{
id: {
type: Sequelize.INTEGER,
primaryKey: true
},
name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
rememberToken: {
type: Sequelize.STRING,
field: 'remember_token'
}
},
{
underscored: true,
timestamps: true,
createdAt: 'created_at',
updatedAt: 'updated_at'
}
);
So far the best solution I found to do this is to use getters and setters.
They will - however - not affect results in object.values or object.toJSON(). You'll need your own serialization methods if you want to use these.
Related
Tagcategories Model
export const TagCategories = sequelize.define(
"tag_categories",
{
categoryId: {
type: DataTypes.INTEGER,
field: "category_id",
autoIncrement: true,
primaryKey: true,
},
title: {
type: DataTypes.STRING(50),
field: "title",
allowNull: false,
unique: true,
},
},
);
TagCategories.hasMany(TagGroups, {
foreignKey: "categoryId",
sourceKey: "categoryId",
});
export default TagCategories;
TagGroups Model
export const TagGroups = sequelize.define(
"tag_groups",
{
tagGroupId: {
type: DataTypes.INTEGER,
field: "tag_group_id",
autoIncrement: true,
primaryKey: true,
},
categoryId: {
type: DataTypes.INTEGER,
field: "category_id",
allowNull: false,
},
title: {
type: DataTypes.STRING(50),
field: "title",
allowNull: false,
unique: true,
},
},
);
In the above models I establish oneToMany relationship between the TagCategories and TagGroups
But I want to fetch the record from the TagGroup table with the TagCategories details.
Thanks in advance
Did you look at examples in official documentation?
Also, you need to add an association from TagGroups to TagCategories:
// there is no need to indicate `sourceKey` if this field is a primary key
TagGroups.belongsTo(TagCategories, {
foreignKey: "categoryId",
});
It's better to define all associations in static functions and call all of them separately after all models will be registered.
See the question and my answer here how to do it
In your case, the final request would be something like this
const tagGroup = await TagGroups.findOne({
where: {
tagGroupId: groupId
},
include: [{
model: TagCategories
}]
})
module.exports = function (sequelize, Sequelize) {
var User = sequelize.define('user', {
id: { autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER },
firstname: { type: Sequelize.STRING, notEmpty: true },
lastname: { type: Sequelize.STRING, notEmpty: true },
//username: { type: Sequelize.TEXT },
//about: { type: Sequelize.TEXT },
mobileno: { type: Sequelize.STRING },
email: { type: Sequelize.STRING, validate: { isEmail: true } },
password: { type: Sequelize.STRING, allowNull: false },
last_login: { type: Sequelize.DATE },
//status: { type: Sequelize.ENUM('active', 'inactive'), defaultValue: 'active' }
});
return User;
}
Everything else is posting fine but mobileno is being posted as null in database.
I tried setting mobile no as allowNull = false but that gives me an error.
I also tried changing string to text but that didn't help either...
this is the eroor after adding allowNull=false..
After checking the documentation your code is working normally.
// setting allowNull to false will add NOT NULL to the column, which means an error will be
// thrown from the DB when the query is executed if the column is null. If you want to check that a value
// is not null before querying the DB, look at the validations section below.
title: { type: Sequelize.STRING, allowNull: false },
Before saving to the db, you need to validate your info to make sure that mobileno is not null. Once you have a value for mobileno you can save it to the db.
Your problems is in your data not in your sequelize model
Based on your question I think you send the empty value for mobileno field
About AllowNull parameter: when you will set the false it's means sequelize will return error if you will not pass parameter (which happens in your case)
By default AllowNull value is true
My suggestion is to check you data before insert query also when you will run create command using sequelize check console it's will show you insert into sql format
I need to run a join query using sequelize and I have been reading the documentation at sequelize doc. But as I run the following snippet, I get an error.
let channelUsersM = UserModel.get(); // Table name: channel_users
let channelM = ChannelModel.get(); // Table name: channel
channelUsersM.belongsTo(channelM, {as: 'channel',foreign_key: 'channel_id',targetKey:'id'});
channelM.hasMany(channelUsersM,{foreign_key: 'channel_id'});
channelUsersM.findAll({
attributes: ['username'],
where: {
usertype: this.userType,
channel: {
name: channelName
}
},
include: [channelM]
}).then((r) => {
resolve(r);
}).catch((err) => {
reject(err);
});
Error says: channel is not associated to channel_users!
What could be the reason for this? I know how to directly run a SQL query using sequelize, but I do not want to go with it.
For easier understanding here, is the equivalent sql query that I am trying with sequelize:
select cu.username from channel as ch left join
channel_users as cu on ch.id = cu.channel_id
ch.name = 'some-name' and cu.usertype = 'some-type';
Here is the definition of models if required:
For channel_users:
channel_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
field: 'channel_id'
},
userid: {
type: Sequelize.INTEGER,
field: 'userid'
},
username: {
type: Sequelize.CHAR(255),
field: 'username'
},
password: {
type: Sequelize.TEXT,
field: 'password'
},
usertype: {
type: Sequelize.ENUM('user', 'moderator','speaker','owner'),
field: 'usertype'
}
For channel:
id: {
type: Sequelize.INTEGER,
field: 'id',
autoIncrement: true,
primaryKey: true
},
name: {
type: Sequelize.CHAR(255),
field: 'name'
},
display_name: {
type: Sequelize.TEXT,
field: 'display_name'
},
creatorid: {
type: Sequelize.INTEGER,
field: 'creatorid'
},
password: {
type: Sequelize.TEXT,
field: 'password'
},
createdAt: {
type: Sequelize.DATE,
field: 'createdAt'
},
modifiedAt: {
type: Sequelize.DATE,
field: 'modifiedAt'
}
You have defined an alias in the belongsTo association, so you also need to include the alias in include attribute when querying. Moreover, the channel.name column value should also be included in the include object of the query.
channelUsersM.findAll({
attributes: ['username'],
where: {
usertype: this.userType
},
include: [
{
model: channelM,
as: 'channel',
attributes: [],
where: { name: channelName }
}
]
}).then((r) => {
resolve(r);
}).catch((err) => {
reject(err);
});
The attributes: [] in include is added in order to prevent returning any fields from the channel table (according to you query you want only the username field from channel_users table).
I am new to NodeJs/sailsJS.
I have following models:
Person
module.exports = {
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
person_id: {
type: 'integer',
primaryKey: true,
autoIncrement: true
},
user: {
model: 'user'
},
person_name: {
type: 'string',
required: true,
size: 128
},
person_birthdate: {
type: 'date'
},
person_gender: {
type: 'string',
size: 1
}
}
};
User
module.exports = {
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
user_id: {
type: 'integer',
primaryKey: true,
autoIncrement: false
},
person: {
model: 'person'
}
}
};
It creates column person in user table and column user in person table. How do I stop these columns to pop up and still be able to use waterline. Entity Framework in C# MVC is able to provide that functionality, so I think there might be a way to do it in SailsJs.
Try to add in file config/models.js this line: migrate: 'safe' to exported configuration.
About model settings you can read here: sailsjs.org/documentation
So, assume we have that Sequelize model:
var User = sequelize.define("User", {
id: {
type: DataTypes.STRING(45),
allowNull: false,
primaryKey: true
},
password: {
type: DataTypes.STRING(60),
allowNull: false
},
email: {
type: DataTypes.STRING(45),
allowNull: false,
unique: true
},
firstName: {
type: DataTypes.STRING(45),
allowNull: true,
defaultValue: null
}
},
{
tableName: 'profiles',
classMethods: {
associate: function(models) {
User.belongsToMany(User, {through: 'friends', as:'friend'});
}
}
});
after calling associate() method, it will create an extra table friends with columns userId, friendId, createdAt and updatedAt. The case is I need to use this table with safe-deleting mode, in other words, I have to add 'deleted' column somehow. I tried to use paranoid: true in belongsToMany's attributes, didn't work. Is there any ways to do it?
Maybe you can create an model/table which name is Friend. And you can set paranoid: true in that model. And when you deleted an User, it keeps User's friend relation was keeping in that model.
I hope it works. :)