I have a schema(table) like following in seqluelize:
const schema = sequelize.define("order_entry_header", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
date: {
type: DataTypes.TEXT,
},
sub_total: {
type: DataTypes.DOUBLE,
},
...
});
My requirement is whenever I call or use or include this schema order_entry_header in
any place in my app I want date column in to format in a readable text in a different column called date_format
In simple sql this should be something like below:
SELECT
id,
date,
DATE_FORMAT(date, "%d/%m/%Y") as date_format
...
FROM order_entry_header;
I am joining/fetching this table data in numerous places and every-time I have to add extra column to get the formatted date specifically. I want this to be automated.
.
.
With instanceMethod it can be performed. but I have to call the method every-time I get the data which is a little confusing sometimes.
.
.
Is there any ways to do so?
You can try to use Default scope (see Scopes)
const schema = sequelize.define("order_entry_header", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
date: {
type: DataTypes.TEXT,
},
sub_total: {
type: DataTypes.DOUBLE,
},
...
}, {
defaultScope: {
attributes: [{ include: [[Sequelize.fn('DATE_FORMAT', Sequelize.col('date')), 'date_format']]}]
active: true
}
}
});
Related
here is my course schema
const CourseSchema = new Schema(
{
courseName: {
type: String,
required: true,
lowercase: true,
},
comments: [
[
{
user: {
type: Schema.Types.ObjectId,
ref: "Users",
required: true,
},
comment: {
type: String,
required: true,
},
createdAt: {
type: Date,
required: true,
},
},
],
],
},
{
timestamps: true,
}
);
const Course = mongoose.model("Course", CourseSchema);
I want to populate the user field. I've tried many stack overflow solutions but none of them works for me.
I populated the model like this but, doing so it only populates the first index the of every model.
courses = await Course.findOne({}).populate({
path: "comments.0.0.user",
});
You can populate another level deeper, here's what you need to do:
db.Course.findOne({}).populate({"path":"comments",populate:[{
path:"user",
model:"Users"
}]})
Another way of nested populating data:
db.Course.findOne({}).populate("comments.user")
I've been trying to use Sequelize to manage a store front mysql db.
I followed the docs here - https://sequelize.org/master/manual/assocs.html
And did (like they said)
const Customer = sequelize.define(
"customers",
{
customer_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
first_name: {
type: DataTypes.STRING,
allowNull: false,
},
last_name: DataTypes.STRING,
},
{ tableName: "customers" }
);
const Order = sequelize.define(
"orders",
{
order_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
customer_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
},
{ tableName: "orders" }
);
and then announce the foregin key like so:
Customer.hasMany(Order, {
foreignKey: 'customer_id'
});
Order.belongsTo(Customer);
And it creates duplicate foregin key, both the customer_id I specified and customerID as the default one.
I can overcome this by also defying foreginKey option in the belongsTo tab.
But even then I get this weird behavior that every time I run the server it "adds" another, like in the picture (from heidiSQL).
I have tried to remove the field from the define() method like #tam.teixeira suggested
And replaced the code to be:
Customer.hasMany(Order, { foreignKey: "customerID"});
Order.belongsTo(Customer);
But it still creates 2 foreginKey that way
[![enter code here][2]][2]
You need to remove the definition of
customer_id: {
type: DataTypes.INTEGER,
allowNull: false,
}
from the orders model, sequelize automatically handles that field, also since its NOT NULL you need to add that condition to the association :
Customer.hasMany(Order, {
foreignKey: {
name: 'customer_id',
allowNull: false
}
});
I am creating a model in sequelize as:
const Desk = sequelize.define('Desk', {
id: {
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
number: {
type: DataTypes.INTEGER,
allowNull: false,
},
},
{
indexes: [
{
unique: true,
fields: ['store_id', 'number'],
message: 'A desk with same number exists on this store'
}
],
tableName: 'desk',
underscored: true,
});
I create an association as such:
Desk.belongsTo(models.Store, {
foreignKey: {
name: 'storeId',
allowNull: false
}
});
I explicitly specify the name of the foreign key so that I can add it as an index.
The problem arises when I try to create a row as such:
const data = { number: 4, storeId: 1 };
await Desk.create(data);
The above code raises an exception that StoreId cannot be null even though I explicitly changed the foreign key to storeId. Even if I try changing the data to
const data = { number: 4, StoreId: 1 };
I get the error: storeId cannot be null
I don't understand if I making some mistake in creating the model but it should not be asking me for multiple values of same field.
I have my model :
const User = sequelize.define(
'User',
{
user_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: DataTypes.STRING(100),
allowNull: false,
validate: {
notEmpty: true,
},
},
description: {
type: DataTypes.STRING(1000),
allowNull: false,
},
},
{
tableName: 'user',
getterMethods: {
shortDescription: function(size) {
return this.description.substring(0, size);
},
},
}
);
I added shortDescription as an example of what I want to do, but I'm not sure how to use it. I want ALL my queries to return a modified description.
const users = await User.findAndCountAll({
limit,
offset,
attributes: {
include: [[Sequelize.fn('LEFT', Sequelize.col('description'), myLength), 'description']],
},
});
Here I'm achieving the same goal with a custom function, but assuming I have multiple functions and subqueries, I feel like re-writing the include clause is a bit inefficient. Ultimately, if a myLength is specified, I want the description to be trimmed, otherwise, have a default value set in the model that trims it.
You could use Model expansion.
After your model's code, I believe you could write something like :
User.Instance.prototype.getShortDescription = function(length) {
return this.description.substring(0, length);
}
I am setting up Sequelize to make it easier to manipulate an MSSQL database.
I have attempted to define a table named 'Stock', but when I try and query this it does all sorts of weird things.
Here is my code for defining it:
const Stock = sequelize.define('Stock', {
StockID: {
type: Sequelize.INTEGER
},
TradeName: {
type: Sequelize.STRING
},
ProductGroupID: {
type: Sequelize.INTEGER
},
ProductClassID: {
type: Sequelize.INTEGER
},
ClubID: {
type: Sequelize.INTEGER
},
NettIntoStore: {
type: Sequelize.STRING
},
NegotiatedCost: {
type: Sequelize.STRING
},
MaximumSOH: {
type: Sequelize.INTEGER
},
OrderCategory: {
type: Sequelize.SMALLINT
},
LastCountDate: {
type: Sequelize.DATE
},
RobotStoreInFridge: {
type: Sequelize.SMALLINT
},
NoShelfLabels: {
type: Sequelize.INTEGER
},
SOLayby: {
type: Sequelize.REAL
},
});
// force: true will drop the table if it already exists
Stock.findOne().then(stock => {
console.log(stock.get('TradeName'));
});
Now running this normally. I.E. getting the first stock row would be easy; but it tires to referrence 'Stocks' in the query for some reason as seen in the code:
I dont wish to add a new primary ID, that is already set as StockID (I imagine I have to set that myself next to type, but at the moment I simply want to get an existing database (Stock) and simply query it and update certain rows.
Sequelize will assume your table has a id primary key property by default.
To define your own primary key:
sequelize.define('collection', {
uid: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true // Automatically gets converted to SERIAL for postgres
}
});
sequelize.define('collection', {
uuid: {
type: Sequelize.UUID,
primaryKey: true
}
});
READ MORE