Fetch jsonb column of postgres db - node.js

I am using node-postgres to select and insert data into postgres. I have some column of jsonb type which I am fetching from db by using below query
getEmployee() {
return SELECT empId, empData FROM employee WHERE empId = $1;
}
where empData is jsonb type of column. Below is code snippet which use above query.
const employee = await DBService.query(pgObj.getEmployee(), [empId]);
when I am trying to get empData from employee I am getting empty value.
const { empData } = employee;
I am not sure what I am missing here. Is this the correct way to fetch josnb column of postgreas db in nodejs?

Are you sure empdata is even populated, in the database? Maybe it's empty.
Also, what are the jsonb fields of empdata?
To get the actual sub-fields of empdata, you need the ->> operator. eg:
get the whole json object as text
SELECT empId, empData::text
FROM employee where empId = $1
get individual attributes
SELECT empId, empData->>annual_pay as salary
FROM employee WHERE empId = $1;
etc...
You can also try
Have a look here: https://kb.objectrocket.com/postgresql/how-to-query-a-postgres-jsonb-column-1433
I haven't tried these out, I'm not in front of postgres right now.

Related

How to get related field value from database in odoo 11 and postgresql?

I am trying to get a related field value from database, but it showing column 'column_name' does not exist.
When i try to find out the value of product_id or using join to find the common data between sale.order and product.product Model . but it showing column 'column_name' does not exist.
In sale.order model the field defination is like
product_id = fields.Many2one('product.product', related='order_line.product_id', string='Product')
But when i try to join two table like below code to fetch all data as per product, like below code.
select coalesce(p.name,'Unassigned Product'), count(*) from sale_order o left join product_product p on o.product_id = p.id where o.state = 'sale' group by p.name;
It showing below error,
column o.product_id does not exist
LINE 1: ... from sale_order o left join product_product p on o.product_...
When i try to get data from sale_order table like below code.
select product_id from sale_order;
It showing below error.
column "product_id" does not exist
Can any one help me to get that value.
To access a related field from database , you have to use the store=True , keyword.
Rewrite your field definition as,
product_id = fields.Many2one('product.product', related='order_line.product_id', string='Product', store=True)
and uninstall and install the module.

Pass column name as argument - Postgres and Node JS

I have a query (Update statement) wrapped in a function and will need to perform the same statement on multiple columns during the course of my script
async function update_percentage_value(value, id){
(async () => {
const client = await pool.connect();
try {
const res = await client.query('UPDATE fixtures SET column_1_percentage = ($1) WHERE id = ($2) RETURNING *', [value, id]);
} finally {
client.release();
}
})().catch(e => console.log(e.stack))
}
I then call this function
update_percentage_value(50, 2);
I have many columns to update at various points of my script, each one needs to be done at the time. I would like to be able to just call the one function, passing the column name, value and id.
My table looks like below
CREATE TABLE fixtures (
ID SERIAL PRIMARY KEY,
home_team VARCHAR,
away_team VARCHAR,
column_1_percentage INTEGER,
column_2_percentage INTEGER,
column_3_percentage INTEGER,
column_4_percentage INTEGER
);
Is it at all possible to do this?
I'm going to post the solution that was advised by Sehrope Sarkuni via the node-postgres GitHub repo. This helped me a lot and works for what I require:
No column names are identifiers and they can't be specified as parameters. They have to be included in the text of the SQL command.
It is possible but you have to build the SQL text with the column names. If you're going to dynamically build SQL you should make sure to escape the components using something like pg-format or use an ORM that handles this type of thing.
So something like:
const format = require('pg-format');
async function updateFixtures(id, column, value) {
const sql = format('UPDATE fixtures SET %I = $1 WHERE id = $2', column);
await pool.query(sql, [value, id]);
}
Also if you're doing multiple updates to the same row back-to-back then you're likely better off with a single UPDATE statement that modifies all the columns rather than separate statements as they'd be both slower and generate more WAL on the server.
To get the column names of the table, you can query the information_schema.columns table which stores the details of column structure of your table, this would help you in framing a dynamic query for updating a specific column based on a specific result.
You can get the column names of the table with the help of following query:
select column_name from information_schema.columns where table_name='fixtures' and table_schema='public';
The above query would give you the list of columns in the table.
Now to update each one for a specific purpose, You can store the result set of column name to a variable and pass that variable to the function to perform the required action.

Querying cassandra database with an array

I am trying to query my cassandra database to return data from a list of names held on an array server side. This is held as an array.
I know the data I am accessing is stored as a string in my database and so I have appended single quotes around it (I have tried with and without this but no luck).
Here is my query.
const arr = ["ukcust1","ukcust2","ukcust5"];
//Here I append single quotes before and after to each string if needed
const query = "SELECT * FROM table_name WHERE name = ?";
client.execute(query, arr, { prepare:true }, function (err, result) {
..//Code
};
What am I missing here? I want the query to be:
SELECT * FROM table_name WHERE name = each of the names in the array 'arr';
If name were a clustering key, then you could query with "in" and "allow filtering" like this:
select * from table_name where name in ('ukcust1','ukcust2','ukcust3') allow filtering
Assuming name is not a clustering key, you could use a clustering key (e.g., date_of_birth) if it made logical sense -- that is, if filtering by date made sense in relation to the name -- like this:
select * from table_name where date_of_birth in (1969, 1972) name in ('ukcust1','ukcust2','ukcust3') allow filtering
If you can't do either of those things, you will need to loop through the array with Javascript (e.g., foreach).
The correct input of the query parameters is an array of values. In this case, it would be an array of parameters containing a single item, that is an array of names.
const arr = ["ukcust1","ukcust2","ukcust5"];
const query = "SELECT * FROM table_name WHERE name = ?";
// Note the array containing a single item
const parameters = [ arr ];
client.execute(query, parameters, { prepare: true }, callback);
See more info in the documentation: https://docs.datastax.com/en/developer/nodejs-driver/3.5/faq/#how-can-i-use-a-list-of-values-with-the-in-operator-in-a-where-clause

not in query and select one field from second collection

My requirement is to count all the data whose particular id is not in reference collection. The equivalent SQL query would go as below:
select count(*) from tbl1 where tbl.arr.id not in (select id from tbl2)
I've tried as below, but got stuck up on fetching single field i.e. id from 2nd query.
db.coll1.find(
{$not:
{"arr.id":
{$in:
{db.coll2.find()}//how would I fetch a single column from
//2nd coll2
}
}
}
).count()
Also, Please note that arr.id is an ObjectId stored in collection coll1 and same will go with collection coll2. Should special care be taken while fetching the id like say ObjectId(id)?
Update - I am using mongo db version 3.0.9
I had to use $nin to check for not in condition and get the array in a different format as the version of mongodb was 3.0.9. Below is how I did it.
db.coll1.find({"arr.id":{$nin:[db.coll2.find({},["id"])]}}).count()
For mongodb v>=3.2 it would be as below
db.coll1.find({"arr.id":{$nin:[db.coll2.find({},"id")]}}).count()

Error in Linq: The text data type cannot be selected as DISTINCT because it is not comparable

I've a problem with LINQ. Basically a third party database that I need to connect to is using the now depreciated text field (I can't change this) and I need to execute a distinct clause in my linq on results that contain this field.
I don't want to do a ToList() before executing the Distinct() as that will result in thousands of records coming back from the database that I don't require and will annoy the client as they get charged for bandwidth usage. I only need the first 15 distinct records.
Anyway query is below:
var query = (from s in db.tSearches
join sc in db.tSearchIndexes on s.GUID equals sc.CPSGUID
join a in db.tAttributes on sc.AttributeGUID equals a.GUID
where s.Notes != null && a.Attribute == "Featured"
select new FeaturedVacancy
{
Id = s.GUID,
DateOpened = s.DateOpened,
Notes = s.Notes
});
return query.Distinct().OrderByDescending(x => x.DateOpened);
I know I can do a subquery to do the same thing as above (tSearches contains unique records) but I'd rather a more straightfoward solution if available as I need to change a number of similar queries throughout the code to get this working.
No answers on how to do this so I went with my first suggestion and retrieved the unique records first from tSearch then constructed a subquery with the non unique records and filtered the search results by this subquery. Answer below:
var query = (from s in db.tSearches
where s.DateClosed == null && s.ConfidentialNotes != null
orderby s.DateOpened descending
select new FeaturedVacancy
{
Id = s.GUID,
Notes = s.ConfidentialNotes
});
/* Now filter by our 'Featured' attribute */
var subQuery = from sc in db.tSearchIndexes
join a in db.tAttributes on sc.AttributeGUID equals a.GUID
where a.Attribute == "Featured"
select sc.CPSGUID;
query = query.Where(x => subQuery.Contains(x.Id));
return query;

Resources