missing FROM-clause entry for table - postgresql

My app uses sequelize 6.x with postgresql 14 to select artwork with either forsale or fortrade or both. Both forsale and fortrade belong to artwork. Here is the code:
let artworks = await Artwork.findAll({
limit:req.query.limit? req.query.limit:1000,//<<==limit:1000
include:[{
model:ForSale,
required: false,
attributes:["id", "escrow_value", "active_date", "buyer_id", "deposit_date", "close_date", "buy_date","dispute_date", "seller_refund_value", "buyer_refund_value"]
},{
model:ForTrade,
required: false,
attributes:["id", "escrow_value", "active_date", "bidder_id","poster_refund_value","bidder_refund_value","bid_date","poster_deposit_date","bidder_deposit_date","transaction_closed","close_date"]
}],
where: {
uploader_id:req.viewer.id, //<<==here req.viewer.id is 1
status:"active",
deleted:false,
//<<<< either ForSale record exists or ForTrade record exists or both exist.
[Op.or]: [{
'$ForSale.id$': {
[Op.ne]: null
}
},{
'$ForTrade.id$': {
[Op.ne]: null
}
}]
},
attributes:{exclude:['fort_token']},
order:[['id', 'DESC']]
});
Here is the SQL executed and the error:
0|server | Executing (default): SELECT "artwork".*, "forsales"."id" AS "forsales.id", "forsales"."escrow_value" AS "forsales.escrow_value", "forsales"."active_date" AS "forsales.active_date", "forsales"."buyer_id" AS "forsales.buyer_id", "forsales"."deposit_date" AS "forsales.deposit_date", "forsales"."close_date" AS "forsales.close_date", "forsales"."buy_date" AS "forsales.buy_date", "forsales"."dispute_date" AS "forsales.dispute_date", "forsales"."seller_refund_value" AS "forsales.seller_refund_value", "forsales"."buyer_refund_value" AS "forsales.buyer_refund_value", "fortrades"."id" AS "fortrades.id", "fortrades"."escrow_value" AS "fortrades.escrow_value", "fortrades"."active_date" AS "fortrades.active_date", "fortrades"."bidder_id" AS "fortrades.bidder_id", "fortrades"."poster_refund_value" AS "fortrades.poster_refund_value", "fortrades"."bidder_refund_value" AS "fortrades.bidder_refund_value", "fortrades"."bid_date" AS "fortrades.bid_date", "fortrades"."poster_deposit_date" AS "fortrades.poster_deposit_date", "fortrades"."bidder_deposit_date" AS "fortrades.bidder_deposit_date", "fortrades"."transaction_closed" AS "fortrades.transaction_closed", "fortrades"."close_date" AS "fortrades.close_date" FROM (SELECT "artwork"."id", "artwork"."name", "artwork"."author", "artwork"."category_id", "artwork"."wt_g", "artwork"."production_year", "artwork"."dimension", "artwork"."uploader_id", "artwork"."description", "artwork"."note", "artwork"."tag", "artwork"."deleted", "artwork"."status", "artwork"."artwork_data", "artwork"."last_updated_by_id", "artwork"."createdAt", "artwork"."updatedAt" FROM "artworks" AS "artwork" WHERE ("ForSale"."id" IS NOT NULL OR "ForTrade"."id" IS NOT NULL) AND "artwork"."uploader_id" = 1 AND "artwork"."status" = 'active' AND "artwork"."deleted" = false ORDER BY "artwork"."id" DESC LIMIT '1000') AS "artwork" LEFT OUTER JOIN "forsales" AS "forsales" ON "artwork"."id" = "forsales"."artwork_id" LEFT OUTER JOIN "fortrades" AS "fortrades" ON "artwork"."id" = "fortrades"."artwork_id" ORDER BY "artwork"."id" DESC;
0|server | Error in myWorkInDeal : Error
0|server | at Query.run (/home/node-xyz/node_modules/sequelize/lib/dialects/postgres/query.js:50:25)
0|server | at /home/node-xyz/node_modules/sequelize/lib/sequelize.js:314:28
0|server | at async PostgresQueryInterface.select (/home/node-xyz/node_modules/sequelize/lib/dialects/abstract/query-interface.js:407:12)
0|server | at async Function.findAll (/home/node-xyz/node_modules/sequelize/lib/model.js:1134:21)
0|server | at async /home/node-xyz/routes/artworks.js:562:24 {
0|server | name: 'SequelizeDatabaseError',
0|server | parent: error: missing FROM-clause entry for table "ForSale"
0|server | at Parser.parseErrorMessage (/home/node-xyz/node_modules/pg-protocol/dist/parser.js:287:98)
0|server | at Parser.handlePacket (/home/node-xyz/node_modules/pg-protocol/dist/parser.js:126:29)
0|server | at Parser.parse (/home/node-xyz/node_modules/pg-protocol/dist/parser.js:39:38)
0|server | at Socket.<anonymous> (/home/node-xyz/node_modules/pg-protocol/dist/index.js:11:42)
0|server | at Socket.emit (node:events:513:28)
0|server | at addChunk (node:internal/streams/readable:315:12)
0|server | at readableAddChunk (node:internal/streams/readable:289:9)
0|server | at Socket.Readable.push (node:internal/streams/readable:228:10)
0|server | at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
0|server | length: 120,
0|server | severity: 'ERROR',
0|server | code: '42P01',
0|server | detail: undefined,
0|server | hint: undefined,
0|server | position: '1615',
0|server | internalPosition: undefined,
0|server | internalQuery: undefined,
0|server | where: undefined,
0|server | schema: undefined,
0|server | table: undefined,
0|server | column: undefined,
0|server | dataType: undefined,
0|server | constraint: undefined,
0|server | file: 'parse_relation.c',
0|server | line: '3541',
0|server | routine: 'errorMissingRTE',
The same error is repeated for table ForTrade. The cases in online posts about this error do not fit in this case (caused by UNION). What is missing with the sequelize code?
Here is the model def and association:
Artwork.init({
name: {
type: DataTypes.STRING,
validate:{
len:{
args:[1,55],
msg:"max 55 chars",
},
},
},
author: {
type:DataTypes.STRING
},
category_id:{ //such as paiting, photo, calligraphy
type:DataTypes.INTEGER,
},
wt_g: {
type:DataTypes.DECIMAL(10,2),
},
production_year: {
type: DataTypes.STRING,
},
dimension: {
type:DataTypes.STRING,
},
uploader_id: {
type: DataTypes.INTEGER,
notNull:true,
},
description: {
type: DataTypes.TEXT,
},
note: {
type:DataTypes.TEXT
},
tag: {
type:DataTypes.ARRAY(DataTypes.STRING),
},
deleted: {
type:DataTypes.BOOLEAN,
defaultValue:false,
},
status: {
type: DataTypes.STRING,
defaultValue:"active"
},
artwork_data: {
type: DataTypes.JSONB
},
last_updated_by_id: {type: DataTypes.INTEGER},
createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE
}
Here is forsale:
ForSale.init({
buyer_id: {
type:DataTypes.INTEGER
},
artwork_id: {
type:DataTypes.INTEGER,
allowNull:false,
},
status: {
type:DataTypes.STRING,
},
price: {
type:DataTypes.INTEGER,
allowNull:false
},
shipping_cost: {
type:DataTypes.INTEGER,
},
shipping_method: {
type:DataTypes.INTEGER, //1-express, 2-air, 3-ground
},
transaction_closed:{
type: DataTypes.BOOLEAN,
defaultValue: false,
},
seller_refund_value:{type: DataTypes.INTEGER},
buyer_refund_value:{type: DataTypes.INTEGER},
escrow_value:{type: DataTypes.INTEGER},
deposit_date:{type: DataTypes.DATE},
buy_date:{type: DataTypes.DATE},
dispute_date:{type: DataTypes.DATE},
active_date:{type: DataTypes.DATE},
close_date:{type: DataTypes.DATE},
seller_receive_payment_date:{type: DataTypes.DATE},
buyer_receive_product_date:{type: DataTypes.DATE},
forsale_data: {
type: DataTypes.JSONB, //buyer_hashaddress, seller_hashaddress, trade_expense ...
},
deployed_address: {
type: DataTypes.STRING
},
smartcontract_name: {
type: DataTypes.STRING,
},
last_updated_by_id: {type: DataTypes.INTEGER},
createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE
}
Here is fotrade:
ForTrade.init({
bidder_id: {
type:DataTypes.INTEGER
},
artwork_id: {
type:DataTypes.INTEGER,
allowNull:false,
},
status: {
type:DataTypes.STRING,
},
price: {
type:DataTypes.INTEGER,
allowNull:false
},
shipping_method: { //1-express, 2-air, 3-ground
type:DataTypes.INTEGER,
},
shipping_cost: {
type:DataTypes.INTEGER,
},
transaction_closed:{
type: DataTypes.BOOLEAN,
defaultValue:false,
},
poster_refund_value:{type: DataTypes.INTEGER},
bidder_refund_value:{type: DataTypes.INTEGER},
escrow_value:{type: DataTypes.INTEGER}, //total deposit is 2*escrow_value
poster_deposit_date:{type: DataTypes.DATE},
bidder_deposit_date:{type: DataTypes.DATE},
bid_date:{type: DataTypes.DATE},
active_date:{type: DataTypes.DATE},
poster_receive_product_date:{type: DataTypes.DATE},
poster_ship_product_date:{type: DataTypes.DATE},
bidder_receive_product_date:{type: DataTypes.DATE},
bidder_ship_product_date:{type: DataTypes.DATE},
close_date:{type: DataTypes.DATE},
fortrade_data: {
type: DataTypes.JSONB, //buyer_hashaddress, seller_hashaddress, trade_expense ...
},
deployed_address: {
type: DataTypes.STRING
},
smartcontract_name: {
type: DataTypes.STRING,
},
last_updated_by_id: {type: DataTypes.INTEGER},
createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE
}
Here is association:
Artwork.hasMany(ForSale, {foreignKey: 'artwork_id'});
Artwork.hasMany(ForTrade, {foreignKey: 'artwork_id'});
ForSale.belongsTo(Artwork, {foreignKey: "artwork_id"});
ForTrade.belongsTo(Artwork, {foreignKey: "artwork_id"})

Related

Get migrations to run on Waterlinejs standalone

Node version: (18.0.0)
DB adapter & version (sails-postgresql#4.0.0):
I kindly require assistance to get migrations to run on waterline standalone version 0.15.0
My config is as follows:
module.exports = {
adapters: {
pg: require('sails-postgresql'),
mysql: require('sails-mysql'),
},
datastores: {
default: {
adapter: 'pg',
host: 'localhost',
port: 5432,
user: 'rcp',
password: 'rcp',
database: 'db_service',
isVersion12OrNewer: true,
},
mysql: {
adapter: 'mysql',
host: 'localhost',
port: 3306,
user: 'db',
password: 'db',
database: 'db_service',
},
},
};
My models:
module.exports = {
identity: 'pet',
datastore: 'default',
primaryKey: 'id',
migrate: 'alter',
attributes: {
id: {
type: 'number',
autoMigrations: { autoIncrement: true },
},
breed: { type: 'string' },
type: { type: 'string' },
name: { type: 'string' },
// Add a reference to User
owner: {
model: 'user',
},
},
};
module.exports = {
identity: 'user',
datastore: 'default',
primaryKey: 'id',
migrate: 'alter',
attributes: {
id: {
type: 'number',
autoMigrations: { autoIncrement: true },
},
firstName: { type: 'string' },
lastName: { type: 'string' },
// Add a reference to Pets
pets: {
collection: 'pet',
via: 'owner',
},
},
};
The bootstrap file:
const Waterline = require('waterline');
const config = require('./config');
const userModel = require('./models/user');
const petModel = require('./models/pet');
const userCollection = Waterline.Collection.extend(userModel);
const petCollection = Waterline.Collection.extend(petModel);
const waterline = new Waterline();
waterline.registerModel(userCollection);
waterline.registerModel(petCollection);
waterline.initialize(config, function (err, ontology) {
if (err) {
console.error(err.message);
return;
}
// Tease out fully initialized models.
let User = ontology.collections.user;
let Pet = ontology.collections.pet;
// Since we're using `await`, we'll scope our selves an async IIFE:
(async () => {
// First we create a user
const user = await User.create({
firstName: 'Neil',
lastName: 'Armstrong',
});
// Then we create the pet
const pet = await Pet.create({
breed: 'beagle',
type: 'dog',
name: 'Astro',
owner: user.id,
});
// Then we grab all users and their pets
const users = await User.find().populate('pets');
console.log(users);
})()
.then(() => {
// All done.
})
.catch((err) => {
console.error(err.message);
}); //_∏_
});
My package.json:
{
"name": "db-service",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "nodemon index.js"
},
"dependencies": {
"sails-mysql": "^2.0.0",
"sails-postgresql": "^4.0.0",
"waterline": "^0.15.0"
},
"devDependencies": {
"nodemon": "^2.0.18"
}
}
The issue I am facing is that when I run the bootstrap file, I get the error below:
Unexpected error from database adapter: relation "public.user" does not exist
Any assistance on this is highly appreciated.
Error Stack:
OperationalError [AdapterError]: Unexpected error from database adapter: relation "public.user" does not exist
at callback (/Users/.../Downloads/musings/db-service/index.js:20:27)
... 20 lines matching cause stack trace ...
at Connection.emit (node:events:539:35) {
cause: Error [AdapterError]: Unexpected error from database adapter: relation "public.user" does not exist
at callback (/Users/.../Downloads/musings/db-service/index.js:20:27)
at /Users/.../Downloads/musings/db-service/node_modules/waterline/lib/waterline.js:731:14
at /Users/.../Downloads/musings/db-service/node_modules/async/dist/async.js:952:25
at iteratorCallback (/Users/.../Downloads/musings/db-service/node_modules/async/dist/async.js:997:17)
at /Users/.../Downloads/musings/db-service/node_modules/async/dist/async.js:847:20
at /Users/.../Downloads/musings/db-service/node_modules/waterline/lib/waterline/utils/system/validate-datastore-connectivity.js:42:14
at /Users/.../Downloads/musings/db-service/node_modules/machine/lib/private/help-build-machine.js:954:24
at handlerCbs.success (/Users/.../Downloads/musings/db-service/node_modules/machine/lib/private/help-build-machine.js:814:26)
at Object.releaseConnection (/Users/.../Downloads/musings/db-service/node_modules/machinepack-postgresql/machines/release-connection.js:79:18)
at wrapper (/Users/.../Downloads/musings/db-service/node_modules/#sailshq/lodash/lib/index.js:3282:19)
at parley.retry (/Users/.../Downloads/musings/db-service/node_modules/machine/lib/private/help-build-machine.js:1076:19)
at parley (/Users/.../Downloads/musings/db-service/node_modules/parley/lib/parley.js:140:5)
at Object.runFn [as releaseConnection] (/Users/.../Downloads/musings/db-service/node_modules/machine/lib/private/help-build-machine.js:461:23)
at /Users/.../Downloads/musings/db-service/node_modules/waterline/lib/waterline/utils/system/validate-datastore-connectivity.js:35:27
at /Users/.../Downloads/musings/db-service/node_modules/machine/lib/private/help-build-machine.js:954:24
at handlerCbs.success (/Users/.../Downloads/musings/db-service/node_modules/machine/lib/private/help-build-machine.js:814:26)
at PendingItem.cb [as callback] (/Users/.../Downloads/musings/db-service/node_modules/machinepack-postgresql/machines/get-connection.js:87:20)
at BoundPool._acquireClient (/Users/.../Downloads/musings/db-service/node_modules/pg-pool/index.js:298:21)
at /Users/.../Downloads/musings/db-service/node_modules/pg-pool/index.js:270:21
at Connection.<anonymous> (/Users/.../Downloads/musings/db-service/node_modules/pg/lib/client.js:253:7)
at Object.onceWrapper (node:events:642:26)
at Connection.emit (node:events:539:35) {
adapterMethodName: 'create',
modelIdentity: 'user',
raw: error: relation "public.user" does not exist
at Parser.parseErrorMessage (/Users/.../Downloads/musings/db-service/node_modules/pg-protocol/dist/parser.js:287:98)
at Parser.handlePacket (/Users/.../Downloads/musings/db-service/node_modules/pg-protocol/dist/parser.js:126:29)
at Parser.parse (/Users/.../Downloads/musings/db-service/node_modules/pg-protocol/dist/parser.js:39:38)
at Socket.<anonymous> (/Users/.../Downloads/musings/db-service/node_modules/pg-protocol/dist/index.js:11:42)
at Socket.emit (node:events:527:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at Readable.push (node:internal/streams/readable:234:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
length: 110,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: '13',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '1363',
routine: 'parserOpenTable'
}
},
isOperational: true,
adapterMethodName: 'create',
modelIdentity: 'user',
raw: error: relation "public.user" does not exist
at Parser.parseErrorMessage (/Users/.../Downloads/musings/db-service/node_modules/pg-protocol/dist/parser.js:287:98)
at Parser.handlePacket (/Users/.../Downloads/musings/db-service/node_modules/pg-protocol/dist/parser.js:126:29)
at Parser.parse (/Users/.../Downloads/musings/db-service/node_modules/pg-protocol/dist/parser.js:39:38)
at Socket.<anonymous> (/Users/.../Downloads/musings/db-service/node_modules/pg-protocol/dist/index.js:11:42)
at Socket.emit (node:events:527:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at Readable.push (node:internal/streams/readable:234:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
length: 110,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: '13',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '1363',
routine: 'parserOpenTable'
}
}

Sequelize Error 42804. will need to rewrite or cast the expressions

I have a project I am working on with sequelize to build and sync the database. I setup a database table called Space. When it tries to sync the database with my other tables. I am getting an error code 42804.
Here is the table:
const seq = require('sequelize');
const { postgres } = require('../index');
const { Images } = require('./Images');
const { Reservation } = require('./Reservation');
const { SpaceAmenities } = require('./SpaceAmenities');
const Space = postgres.define(
'space',
{
id: {type: seq.INTEGER, primaryKey: true, autoincrement: true},
size: {type: seq.INTEGER, require: true,
validate: {isNumeric: true, allowNull: false}
},
amount: {type: seq.FLOAT, require: true,
validate: {isFloat: true, allowNull: false}
},
floor: {type: seq.INTEGER, require: true,
validate: {isNumeric: true, allowNull: false}
},
available: {type: seq.BOOLEAN, require: true, defaultValue: 0,
validate: {isIn: [['0', '1']], isInt: true, allowNull: false}
}
},
{
createdAt: seq.DATE,
updatedAt: seq.DATE
}
)
Space.hasMany(Images, {as: 'imagesId'})
Space.hasMany(Reservation, {as: 'reservationId'})
Space.hasMany(SpaceAmenities, {as: 'spaceAmenitiesId'})
postgres.sync()
.then(() => {
console.log("Space table is connected and synced")
})
.catch((err) => {
console.log("Error syncing the Space table: " + JSON.stringify(err))
})
module.exports.Space = Space;
Error:
Error syncing the Space table: {"name":"SequelizeDatabaseError","parent":{"name":"error","length":184,"severity":"ERROR","code":"42804","hint":"You will need to rewrite or cast the expression.","file":"heap.c","line":"2946","routine":"cookDefault","sql":"CREATE TABLE IF NOT EXISTS \"spaces\" (\"id\" INTEGER , \"size\" INTEGER, \"amount\" FLOAT, \"floor\" INTEGER, \"available\" BOOLEAN DEFAULT 0, \"DATE\" TIMESTAMP WITH TIME ZONE NOT NULL, \"officeId\" INTEGER REFERENCES \"offices\" (\"id\") ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY (\"id\"));"},"original":{"name":"error","length":184,"severity":"ERROR","code":"42804","hint":"You will need to rewrite or cast the expression.","file":"heap.c","line":"2946","routine":"cookDefault","sql":"CREATE TABLE IF NOT EXISTS \"spaces\" (\"id\" INTEGER , \"size\" INTEGER, \"amount\" FLOAT, \"floor\" INTEGER, \"available\" BOOLEAN DEFAULT 0, \"DATE\" TIMESTAMP WITH TIME ZONE NOT NULL, \"officeId\" INTEGER REFERENCES \"offices\" (\"id\") ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY (\"id\"));"},"sql":"CREATE TABLE IF NOT EXISTS \"spaces\" (\"id\" INTEGER , \"size\" INTEGER, \"amount\" FLOAT, \"floor\" INTEGER, \"available\" BOOLEAN DEFAULT 0, \"DATE\" TIMESTAMP WITH TIME ZONE NOT NULL, \"officeId\" INTEGER REFERENCES \"offices\" (\"id\") ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY (\"id\"));"}
not sure how to fix this error with syncing.
There are other tables that are associated with this table includeing
Images:
const seq = require('sequelize');
const { postgres } = require('../index');
const Images = postgres.define(
'images',
{
id: {type: seq.INTEGER, primaryKey: true, autoincrement: true},
image: {type: seq.FLOAT(9, 2), require: true,
validate: {isFloat: true, allowNull: false}
},
},
{
createdAt: seq.DATE,
updatedAt: seq.DATE
}
)
postgres.sync()
.then(() => {
console.log("Images table is connected and synced")
})
.catch((err) => {
console.log("Error syncing the Images table: " + JSON.stringify(err))
})
module.exports.Images = Images;
Reservations:
const seq = require('sequelize');
const { postgres } = require('../index');
const Reservation = postgres.define(
'reservation',
{
id: {type: seq.INTEGER, primaryKey: true, autoincrement: true},
start: {type: seq.DATE, required: true,
validate: {isDate: true, allowNull: false}
},
end: {type: seq.DATE, required: true,
validate: {isDate: true, allowNull: false}
},
amount: {type: seq.FLOAT(9, 2), require: true,
validate: {isFloat: true, allowNull: false}
},
},
{
createdAt: seq.DATE,
updatedAt: seq.DATE
}
)
postgres.sync()
.then(() => {
console.log("Reservation table is connected and synced")
})
.catch((err) => {
console.log("Error syncing the Reservation table: " + JSON.stringify(err))
})
module.exports.Reservation = Reservation;
SpaceAmenities:
const seq = require('sequelize');
const { postgres } = require('../index');
const SpaceAmenities = postgres.define(
'space_amenities',
{
id: {type: seq.INTEGER, primaryKey: true, autoincrement: true},
},
{
createdAt: seq.DATE,
updatedAt: seq.DATE
}
)
postgres.sync()
.then(() => {
console.log("Space_Amenities table is connected and synced")
})
.catch((err) => {
console.log("Error syncing the Space_Amenities table: " + JSON.stringify(err))
})
module.exports.SpaceAmenities = SpaceAmenities;
Your problem is
"available" BOOLEAN DEFAULT 0
PostgreSQL complains about the default value, which cannot be cast to boolean implicitly:
\dCS boolean
List of casts
Source type | Target type | Function | Implicit?
-------------+-------------------+----------+---------------
boolean | character | text | in assignment
boolean | character varying | text | in assignment
boolean | integer | int4 | no
boolean | text | text | in assignment
integer | boolean | bool | no
jsonb | boolean | bool | no
(6 rows)
You should write
"available" BOOLEAN DEFAULT FALSE

how to use arrayFilters and $push to update a same array field at same time

model as follow:
let gardenmodal = new mongoose.Schema({
display:{type:Boolean, default:true},
itemList:[{type:Number,count:Number}]
});
let GardenModel = db.model('GardenModel', gardenmodal);
document as follow:
{ display: true,
itemList:
[ { type: 1, count: 200 },
{ type: 2, count: 81 },
{ type: 3, count: 78 } ],
_id: 5b2e52144c73cb22fc77b92b,
__v: 0 }
I want to update the element with type =1 to make its num decrease 2 and the element with type =2 to make its num decrease 3, at the same time a new element with its type=10, count=100, need to push into the itemList, here is my try:
let res = await GardenModel.findOneAndUpdate({},{
$inc:{"itemList.$[elem1].count":-3, "itemList.$[elem2].count" : -2},
$push:{"itemList":{ type: 10, count: 200 }}
},{
arrayFilters:[{"elem1.type":2},{"elem2.type":3}],
new:true
});
but it works fail:
(node:6596) UnhandledPromiseRejectionWarning: MongoError: Updating the path 'itemList.$[elem1].count' would create a conflict at 'itemList'
at H:\node\wcgroup\node_modules\mongodb-core\lib\connection\pool.js:593:63
at authenticateStragglers (H:\node\wcgroup\node_modules\mongodb-core\lib\connection\pool.js:516:16)
at Connection.messageHandler (H:\node\wcgroup\node_modules\mongodb-core\lib\connection\pool.js:552:5)
at emitMessageHandler (H:\node\wcgroup\node_modules\mongodb-core\lib\connection\connection.js:309:10)
at Socket.<anonymous> (H:\node\wcgroup\node_modules\mongodb-core\lib\connection\connection.js:452:17)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:279:12)
at readableAddChunk (_stream_readable.js:264:11)
at Socket.Readable.push (_stream_readable.js:219:10)
at TCP.onread (net.js:636:20)
what should I do?

postgres using knex/bookshelf relational query

The bootcamp I went to taught postgres using the knex/bookshelf libraries, but at the moment I don't know how to use the reqular queries(ie. SELECT FROM etc...).
I've haven't tried a relational query with the knex/bookshelf libraries until now and I can't get it to work. I've looked at the documentation and as far as I can tell I've used the syntax they say to.
exports.getStudentsByClass = (key) => {
return Classroom.where({ id: key }).fetch({
withRelated: 'student'
})
.then(classroom => {
const students = classroom.related('student')
console.log(classroom.models.map(student => {
studentList.attributes
}))
return classroom
})
.catch(err => {
console.log(err)
})
}
This is the function I am using to query the database. When I console log the data this is what I get
CollectionBase {
model:
{ [Function]
super_: [Function: Events],
extend: [Function: extend],
extended: [Function: extended],
__super__:
ModelBase {
_builder: [Function: builderFn],
_relation: [Function: _relation],
Collection: [Object] },
NotFoundError: [Function: ErrorCtor],
NoRowsUpdatedError: [Function: ErrorCtor],
NoRowsDeletedError: [Function: ErrorCtor],
forge: [Function: forge],
collection: [Function: collection],
count: [Function: count],
fetchAll: [Function: fetchAll],
where: [Function],
query: [Function] },
length: 5,
models:
[ ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c77',
id: 7 },
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c78',
id: 4 },
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c79',
id: 9 },
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c80',
id: 14 },
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c81',
id: 10 } ],
_byId:
{ '4':
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c78',
id: 4 },
'7':
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c77',
id: 7 },
'9':
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c79',
id: 9 },
'10':
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c81',
id: 10 },
'14':
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c80',
id: 14 },
c77:
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c77',
id: 7 },
c78:
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c78',
id: 4 },
c79:
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c79',
id: 9 },
c80:
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c80',
id: 14 },
c81:
ModelBase {
attributes: [Object],
_previousAttributes: [Object],
changed: {},
relations: {},
cid: 'c81',
id: 10 } },
relatedData:
RelationBase {
targetTableName: 'student',
targetIdAttribute: 'id',
type: 'hasMany',
target:
{ [Function]
super_: [Function: Events],
extend: [Function: extend],
extended: [Function: extended],
__super__: [Object],
NotFoundError: [Function: ErrorCtor],
NoRowsUpdatedError: [Function: ErrorCtor],
NoRowsDeletedError: [Function: ErrorCtor],
forge: [Function: forge],
collection: [Function: collection],
count: [Function: count],
fetchAll: [Function: fetchAll],
where: [Function],
query: [Function] },
foreignKey: 'classroom_id',
foreignKeyTarget: undefined,
parentId: 6,
parentTableName: 'classroom',
parentIdAttribute: 'id',
parentAttributes:
{ id: 6,
created_at: 2018-04-24T22:23:34.819Z,
updated_at: 2018-04-24T22:23:34.819Z,
name: ' Classroom 1' },
parentFk: 6 } }
So I'm not sure how to make this work

sails-permissions blacklist read criteria

I have a model with a payment ID, and when I do a GET request it returns the blacklisted item
WorkOrder.create({
id: 1,
requestedDate: new Date(),
user: user[0],
product: product[0],
paid: true,
paymentID: 'abcd12'
})
When I do a simple get call to /workOrder/1
it('should not return the paymentID to the registered user', function(){
return request
.get('/workOrder/1')
.expect(200)
.then(function(res){
console.log(res.body)
return expect(res.body.paymentID).to.equal(undefined)
})
})
It returns the paymentID with the payload
{ user: 322,
product: 733,
id: 1,
requestedDate: '2016-11-06T15:04:41.174Z',
paid: true,
paymentID: 'abcd12',
createdAt: '2016-11-06T15:04:41.179Z',
updatedAt: '2016-11-06T15:04:41.179Z' }
even though in bootstrap.js I have
ok = ok.then(function(){
return PermissionService.grant({
role: 'registered',
model: 'WorkOrder',
action: 'read',
criteria: {blacklist: ['paymentID']}
})
})
and in criteria
sails> Criteria.find({}).then(function(r) {console.log(r)})
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined }
sails> [
{ permission: 11953,
blacklist: [ 'paymentID' ],
createdAt: '2016-11-06T15:11:52.648Z',
updatedAt: '2016-11-06T15:11:52.648Z',
id: 46 } ]
and in permissions
sails> Permission.find({id: 11953}).populate('model').populate('role').then(function(r){console.log(r)})
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined }
sails> [ { model:
{ name: 'WorkOrder',
identity: 'workorder',
attributes:
...
id: 2029 },
role:
{ name: 'registered',
active: true,
createdAt: '2016-11-06T15:11:51.522Z',
updatedAt: '2016-11-06T15:11:51.522Z',
id: 572 },
action: 'read',
relation: 'role',
createdAt: '2016-11-06T15:11:52.640Z',
updatedAt: '2016-11-06T15:11:52.642Z',
id: 11953 } ]
In the WorkOrder model, add this toJSON function near the end of the file (still inside the module.exports). Basically what it does is that before the model ever gets parsed into JSON, it removes the paymentID
// Remove the password when sending data to JSON
toJSON: function() {
var obj = this.toObject();
delete obj.paymentID;
return obj;
},
This link to the Sails Docs explains the concept in further detail along with more examples.