How to bind array to IN condition with Node postgres - node.js

I'm struggling to figure out of to bind an array to an IN query in node pg library.
const env = 'foo';
const sourceTypes = ['one', 'two'];
const resp = await pool.query(
`SELECT source_id, target_id FROM records
WHERE target_env = $1
AND source_type IN ($2)`,
[env, sourceTypes],
);
I've tried several variations and they either error out or don't return any data.
I can make the query when I just use when I manually bind to generate something like this:
SELECT source_id, target_id FROM records
WHERE target_env = 'foo'
AND source_type IN ('one', 'two')
PS: If can provide suggestion on how to actually see the SQL request that PG is generating, that would be extremely helpful!

You can't bind an array to multiple elements of a list in one go. But you can use an array instead of a list by changing in ($2) to =ANY($2)
You can see what queries are getting sent by setting log_statement=all and then viewing the PostgreSQL log file.

Related

Update multiple fields at once with QLDB Node.js driver

I'm trying to implement an API endpoint that handles PATCH or PUT requests, updating the relevant QLDB document with the request payload. I'm trying the following, but it doesn't seem to work:
await driver.executeLambda(async (txn) => {
await txn.execute(
`UPDATE People AS p BY p_id SET ? WHERE p_id = ?`,
requestPayload,
documentId,
);
});
The error I get is:
BadRequestException: Parser Error: at line 1, column 32: Invalid path component, expecting either an IDENTIFIER or STAR, got: QUESTION_MARK with value:
1; Expected identifier for simple path
(I have confirmed that the QLDB statement UPDATE People AS p BY p_id SET p.name = 'John Doe' WHERE p_id = '<document_id>', run in the QLDB web console, does in fact work as desired. I've also confirmed that the values of my variables are as I'd expect -- the first is an object and the second is a string.)
Is this kind of updating not supported by the QLDB Node.js driver?
It looks like your query is missing the field name in the parameterization. It should be SET p.name = ?:
UPDATE People AS p BY p_id SET p.name = ? WHERE p.p_id = ?

Query to fetch details from Cosmos DB

I need to fetch the list of persons from an array(Ex: String[] getPersons) as input. I can't figure out how to compare and fetch data from Cosmos DB using a LINQ expression. I experimented with GetItemLinqQueryable, but I don't know if it's the right way to use it.
var db = Client.GetDatabase(databaseId);
var container = db.GetContainer(containerId);
var q = container.GetItemLinqQueryable<Person>();
var iterator = q.Where(p => p.Name == getPersons[0]).ToFeedIterator();
var results = await iterator.ReadNextAsync();
If I am using the above one, I could only able to get only the first person result but I need to get the other persons in the array as well.
You can use Contains. It is equivalent to ARRAY_CONTAINS in Cosmos DB Array functions.
You can try this code:
var iterator = q.Where(p => getPersons.Contains(p.Name)).ToFeedIterator();

Sails.js: How to find records based on values in associated collection?

I'm looking for a way to make sub-query using Sails.js Waterline. The record has an association with Charge model.
I would expect something like that to work, but that doesn't seem to be supported:
var topRecords = await Record.find({'charge.paid':true});
The closest I got was this:
var topRecords = await Record.find().populate('charge',{paid:true});
but the problem is that it still returns all the Records regardless, just doesn't populate the records that do not match populate where statement.
The reason why I can't search for charges first is that I want to sort the data based on one of the values in Record.
You can fetch the Charges then use .map to get the records from there.
const topCharges = await Charge.find({ paid: true }).populate('records');
const topRecords = topCharges.map(charge => charge.record);

How do I reset query part with knex.js

I tried to find anything here in documentation with no success.
What I would like to do is to clone my query builder and reset some query parts like order by or group by. How can I do that ?
It looks like there is no many methods available for this query parts
And there are clear methods only for selects and where conditions.
How do you do it ?
Example:
const qb = knex
.select('id')
.from('table')
.where({ visibility: 'public' })
// some left joins here
.groupBy('id')
How can I do then something like
const new_qb = qb
.clone()
// remove group by here
.clearSelect()
.count()
To reset query part there is a way for example:
this.qb._clearGrouping('order'); // reset order by
this.qb._clearGrouping('group'); // reset group by
and so on.
You can clone the query and add parts to those individual queries.
Like this:
//base query
let query = knex('table_name').where({id: 1});
const countQuery = query.clone().count();
const selectQuery = query.clone().select().limit(10).offset(0);
return Promise.all([countQuery, selectQuery]);

Log specific postgresql query using pg-promise

I am using pg-promise package with Nodejs to execute PostgreSQL queries. I want to see the queries executed. Only specific queries, say, just one query that I want to debug.
I can see that one recommended way is to use the pg-monitor to catch the events and log them as mentioned here in the examples documentation.
Without using pg-monitor, is there a simple way to just print the prepared query that is executed. I can't see it in the docs.
Example:
db.query("SELECT * FROM table WHERE id = $/id/", {id: 2})
How to print this query to yield?
SELECT * FROM table WHERE id = 2
is there a simple way to just print the prepared query that is executed...
A query in general - yes, see below. A Prepared Query - no, those are by definition formatted on the server-side.
const query = pgp.as.format('SELECT * FROM table WHERE id = $/id/', {id: 2});
console.log(query);
await db.any(query);
And if you want to print all queries executed by your module, without using pg-monitor, simply add event query handler when initializing the library:
const initOptions = {
query(e) {
console.log(e.query);
}
};
const pgp = require('pg-promise')(initOptions);

Resources