Sequelize wont get table from database - javascript

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

Related

How to handle two Sequelize create request to update two different tables in the database using NodeJs

I am using Sequelize and NodeJs to create an API endpoint that updates the two different tables in the database. The front-end is sending form data (text/files). (1) I am extracting the text data and updating the table called shipmentBooking, the first table id is used as foreign key in the 2nd table. simultaneously I am sending the files to the s3 bucket and getting the file paths as an array. (2). once file paths are received I am using the below function to update the 2nd database table called shipmentDoc that has shipmentId as a foreign key. the entire thing is working fine except it does not update the foreign key in the 2nd table.
router.post('/add', upload.array('file'), async (req, res) => {
const shipmentBooking = ShipmentBooking.create({
bookingType: req.body.bookingType,
bookedBy: req.body.bookedBy,
bookingUserId: req.body.bookingUserId
})
try{
const newShipment = await shipmentBooking
console.log('#############')
console.log(newShipment.id)
const results = await s3Uploadsv2(req.files, req.body.bookingUserId)
const addedShipmentDoc = await Promise.all(results.map(result => ShipmentDocs.create({
shipmentId: newShipment.id,
additionalDoc1: result.Location
})));
return res.json({status: 'success', newShipment, addedShipmentDoc})
} catch({error}){
console.log(error)
}
})
Model & Associations:
const ShipmentBookings = db.define('shipmentbookings', {
id:{
type: DataTypes.INTEGER(255),
autoIncrement: true,
allowNull: false,
primaryKey: true
},
UUID:{
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4
},
bookingType: { // invidiual, business
type: DataTypes.STRING(100),
allowNull: false,
},
bookedBy: { // staff, customer
type: DataTypes.STRING(100),
allowNull: false,
},
bookingUserId: { // user id of customer
type: DataTypes.INTEGER(255),
allowNull: true,
}
},{
freezeTableName: true
})
const ShipmentDocs = db.define('shipmentdocs', {
id:{
type: DataTypes.INTEGER(255),
autoIncrement: true,
allowNull: false,
primaryKey: true
},
UUID:{
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4
},
billOfLading: {
type: DataTypes.TEXT('medium'),
allowNull: true,
},
dockReceipt: {
type: DataTypes.TEXT('medium'),
allowNull: true,
},
additionalDoc1: {
type: DataTypes.TEXT('medium'),
allowNull: true,
},
additionalDoc2: {
type: DataTypes.TEXT('medium'),
allowNull: true,
},
additionalDoc3: {
type: DataTypes.TEXT('medium'),
allowNull: true,
},
additionalDoc4: {
type: DataTypes.TEXT('medium'),
allowNull: true,
},
additionalDoc5: {
type: DataTypes.TEXT('medium'),
allowNull: true,
}
},{
freezeTableName: true
})
ShipmentBookings.hasOne(ShipmentDocs ,{foreignKey: 'shipmentId'})
ShipmentDocs.belongsTo(ShipmentBookings ,{foreignKey: 'shipmentId'})
ShipmentDocs Table Image
if the console.log(newShipment.id)
is working as expected,
How about you create the ShipmentBooking within a promise and then after excecuting it, within the "then" ( or "final" ) you run the addedShipmentDoc create query.
Else, console logg the newShipment to see if it has an id field.

returning extra column with formatted date

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
}
}
});

Return custom value for row in sequelize?

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);
}

How can I give primary key and foreign key relationship in Sequelize.js + Postgres.js

I am not able to give relationship into to two tables User and Media
User have profile field which should contain Media Id.
Right now I have written these models User and Media now I want to fetch data using join query.
USER MODEL
const User = sequelize.sequelize.define('users', {
id: {
type: sequelize.Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: sequelize.Sequelize.STRING
},
lastName: {
type: sequelize.Sequelize.STRING
},
email: {
type: sequelize.Sequelize.STRING
},
media_id: {
type: sequelize.Sequelize.INTEGER,
foreignKey: true
}
});
Media.belongsTo(User, {
as: 'media',
foreignKey: {
name: 'media_id',
allowNull: false
}
});
User.find({where: {}, include: [Media]})
User.sync();
MEDIA MODEL
const Media = sequelize.sequelize.define('media', {
id: {
type: sequelize.Sequelize.INTEGER,
primaryKey: true
},
path: {
type: sequelize.Sequelize.STRING
},
type: {
type: sequelize.Sequelize.STRING
}
});
Media.sync();
Firstly, Media.belongsTo(User...) will add a field media_id to your Media model, which is not what you want. Try instead:
User.belongsTo(Media, {
as: 'media',
foreignKey: {
name: 'media_id',
allowNull: false
}
});
Then, you should modify your query:
// Find all users with media where media.id === user.media_id
User.findAll({
include: [{
model: Media,
where: { id: Sequelize.col('user.media_id') }
}]
})

Sequelize.js insert a model with one-to-many relationship

I have two sequelize models with one-to-many relationship. Let's call them Owner and Property.
Assume they are defined using the sails-hook-sequelize as such (simplified).
//Owner.js
module.exports = {
options: {
tableName: 'owner'
},
attributes: {
id: {
type: Sequelize.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING(255)
},
associations: function () {
Owner.hasMany(Property, {
foreignKey: {
name: 'owner_id'
}
});
}
}
//Property.js
module.exports = {
options: {
tableName: 'property'
},
attributes: {
id: {
type: Sequelize.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING(255)
}
}
Now assume I want to insert an Owner record in my database and insert a few property records to associate with the owner. How do I do this?
I'm looking for something like
Owner.create({name:'nice owner',
property: [{name:'nice property'},
{name:'ugly property'}]});
Surprisingly I can't find this in the Sequelize documentation.
You can't associate property existing records when you create the owner, you have to do that right after, with promise chain.
Owner.create({name:'nice owner'}).then(function(owner){
owner.setProperties([{name:'nice property'}, {name:'ugly property'}]).then(/*...*/);
});
To avoid any problems with those associations (owner created but some associations failed), it's better to use transactions.
sequelize.transaction(function(t) {
return Owner.create({name:'nice owner'}, {transaction: t}).then(function(owner){
return owner.setProperties([{name:'nice property'}, {name:'ugly property'}], {transaction : t});
});
});
However, if you want to create new Owner associated to new Properties you can do something like
Owner.create({
name: 'nice owner',
property: [
{ name: 'nice property'},
{ name: 'ugly property'}
]
},{
include: [ Property]
});
See http://docs.sequelizejs.com/en/latest/docs/associations/#creating-with-associations

Categories

Resources