I'm working in a project that uses nodejs API and mysql as database.
I need to make a query that returns all the data of the current month and another one that returns all data between a period.
To get all records, I'm doing this
ContractValue.findAll({
where: {
data: id
},
order: [['data', 'ASC']]
})
The thing is I don't know how to put the conditions inside the where clause
This seems like you are using "Sequelize" as your ORM and from your question i can tell that the problem is that you don't know how to put where conditions.
This should help you!
ContractValue.findAll({
where: {
id: {
[Op.and]: {a: 5}, // AND (a = 5)
[Op.or]: [{a: 5}, {a: 6}], // (a = 5 OR a = 6)
[Op.gt]: 6, // id > 6
[Op.gte]: 6, // id >= 6
[Op.lt]: 10, // id < 10
[Op.lte]: 10, // id <= 10
[Op.ne]: 20, // id != 20
[Op.between]: [6, 10], // BETWEEN 6 AND 10
[Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15
[Op.in]: [1, 2], // IN [1, 2]
[Op.notIn]: [1, 2], // NOT IN [1, 2]
[Op.like]: '%hat', // LIKE '%hat'
[Op.notLike]: '%hat', // NOT LIKE '%hat'
[Op.iLike]: '%hat', // ILIKE '%hat' (case insensitive) (PG only)
[Op.notILike]: '%hat', // NOT ILIKE '%hat' (PG only)
[Op.overlap]: [1, 2], // && [1, 2] (PG array overlap operator)
[Op.contains]: [1, 2], // #> [1, 2] (PG array contains operator)
[Op.contained]: [1, 2], // <# [1, 2] (PG array contained by operator)
[Op.any]: [2,3] // ANY ARRAY[2, 3]::INTEGER (PG only)
},
status: {
[Op.not]: false // status NOT FALSE
}
}
})
You can read more on the documentation (https://sequelize.org/master/manual/models-usage.html) and also you should really know the tools you are using.
There is node module for working with mysql database,first you create mysql connection object:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
then you can build your desired query with it:
connection.query('SELECT * FROM table WHERE 'YOU CONDITIONS...', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
connection.end();
ContractValue.findAll({
where: {
data: {
[Op.between]: [start, end]
}
},
order: [
['data', 'ASC']
]
})
Related
I've been trying for hours and I can't get it to work 100% correctly.
I've using RTK Query with a backend connection to a mysql server.
The issue is that I get all result and not from a specific query, no matter what param I use.
Let me explain:
in the backend (connection is working perfectly) part I have:
app.get("/test", (req, res) => {
const q = 'select * from portfolios'
db.query(q, (err, data) => {
if(err) {return res.json(err)}
return res.json(data)
})
})
in the API-part, I have:
const testerApi = createApi({
reducerPath: 'tester',
baseQuery: fetchBaseQuery({
baseUrl: "http://localhost:8800"
}),
endpoints(builder) {
return {
fetchTesting: builder.query({
query: (name) => {
return {
url: '/test',
params: {
user_id: name.id
},
method: 'GET',
};
},
}),
};
},
});
To call this, I use:
const name = {id:6, na:'iets'};
const results = useFetchTestingQuery(name);
but as a result, I get all content from the mysql test-table, it doesnt filter out the user-id.
So, the result always is something like this:
0
:
{id: 1, user_id: 1, name: 'aaaaaa'}
1
:
{id: 2, user_id: 1, name: 'bbbb'}
2
:
{id: 3, user_id: 2, name: 'cccc'}
3
:
{id: 9, user_id: 3, name: 'dddddd'}
...
So, it is partially working, but how can I get a filtered result?
This might sound a stupid question, but I am a beginner and I've been searching for hours to find a working solution.
I hope someone can help me a little bit ...
Thx,
Peter
tried many things, such as changing the bacnekd side to
app.get("/test/:user_id")
const q = 'select * from portfolios where user_id = ?'
db.query(q, [user_id], (err, data) => {...
and many more but nothing seems to work.
I made the following code:
if (scIDExists) {
var x = con.query('SELECT posX, posY, posZ FROM players WHERE scID = '+socialID+'', function (err, result) {
if (err) {
console.log('The following error happened while selecting scID from [players]: ' + err);
throw err;
}
console.log(result);
});
}
The console.log(result) returns me this:
[ RowDataPacket { posX: 100, posY: 100, posZ: 100 } ]
I want it do return this:
100 100 100
Or atleast something I can work with.
How to? Thank you.
The following log:
[ RowDataPacket { posX: 100, posY: 100, posZ: 100 } ]
means that you have an array of a single element. This element is an instance of RowDataPacket class. You can access the properties like a normal object so you can access the value using:
console.log(result[0].posX) // returns 100
i have this example code
#!/usr/bin/perl
use strict;
use warnings;
use JSON::PP qw( );
use Data::Dumper qw (Dumper);
my $json = JSON::PP->new()->pretty->utf8; # lesbares JSON | Sort numerically
my %ORDER = (id => 1, name => 2);
$json->sort_by(sub {
($ORDER{$JSON::PP::a} // 999) <=> ($ORDER{$JSON::PP::b} // 999)
or $JSON::PP::a cmp $JSON::PP::b
});
print $json->encode(
[
{name => 'ABS700', id => 0, data => [
{
dmsg => 's4F038300', state => 'T: 3.3', user => 'SD_Protocol'
}
]
},
{name => 'GT-WT-02', id => 0, data => [
{
dmsg => 's5410AC5F9800', state => 'T: 17.2 H: 47', user => 'Ralf9'
}
]
},
{name => 'NEU', id => 99, data => [
{
dmsg => 's5410AC5F9800', state => 'T: 17.2 H: 47', user => 'NEUER'
}
]
},
{name => 'Ventus W132', id => 4, data => [
{
dmsg => 'sD66EE1603000', user1 => 'dirigent', comment => 'wind',
readings => [{ state => 'windGuest: 1.2 winddir:0' }]
}
]
},
],
);
I would like to sort this, that the value with the "id => 99" appears at the end.
I could sort all internal values arbitrarily but I need the new outer sorting.
How do I solve this problem?
->sort_by is used to control the order of the elements of hashes.
You want to control the order of the elements of an array.
There's no equivalent mechanism to ->sort_by for arrays because there's no need for one. While you can't naturally control the order in which a hash returns its elements, you can naturally control the order in which an array returns its elements.
my $data = [ ... ];
#$data = sort { $a->{id} <=> $b->{id} } #$data;
print $json->encode($data);
I'm trying to create an api that will return a nested json, coming from two related tables student and studentSubjects
[{
id:"1",
name: "John",
subjects: [{
id:"1",
subject: "Math"
},
{
id:"2",
subject: "English"
}
]
},
{
id:"2",
name: "Peter",
subjects: [{
id:"1",
subject: "Math"
},
{
id:"2",
subject: "English"
}
]
}]
My code looks like this:
this.get = function(res){
db.acquire(function(err, con){
con.query('SELECT * FROM students', function(err, results){
if (err){
res.send({status: 0, message: 'Database error'});
}else{
res.send({status: 1, data: results});
}
})
con.release()
})
}
I know the query should have joins, but it only returns single row. I tried also to make a loop, it won't work because its async
Thanks for your help!!
You cannot create a nested JSON from a MySQL query because it will always return a flat result.
Anyway, to create a nested JSON you should create multiple queries and insert the corresponding array object where needed.
You should really consider using Promises for creating nested queries because it will allow you to make asynchronous operations back to back.
Below code will also close the connection if an error occurs in any of the queries.
PS: I explained each step in the comments in the code below
Imagine having a database called 'School' and three tables called 'Student', 'Subject' and 'Link_student_subject'.
// Instantiate mysql datase variables
const mysql = require( 'mysql' );
const config = {
host : 'localhost',
user : 'root',
password : 'root',
database : 'school'
}
var connection;
// Instantiate express routing variables
const express = require('express');
const router = express.Router();
module.exports = router;
// Wrapper class for MySQL client
// - Constructor creates MySQL connection
// - Connection opened when query is done
// - Promise is resolved when executing
// - Promise returns reject in case of error
// - If promise resolved rows will be the result
class Database {
constructor( config ) {
this.connection = mysql.createConnection( config );
}
query( sql, args ) {
return new Promise( ( resolve, reject ) => {
this.connection.query( sql, args, ( err, rows ) => {
if ( err )
return reject( err );
resolve( rows );
} );
} );
}
close() {
return new Promise( ( resolve, reject ) => {
this.connection.end( err => {
if ( err )
return reject( err );
resolve();
} );
} );
}
}
// Function that will execute a query
// - In case of an error: ensure connection is always closed
// - In case of succes: return result and close connection afterwards
Database.execute = function( config, callback ) {
const database = new Database( config );
return callback( database ).then(
result => database.close().then( () => result ),
err => database.close().then( () => { throw err; } )
);
};
// Instantiate Database
var database = new Database(config);
// Express routing
router.get('/students', function (req, res) {
// Variables - Rows from Students & Subjects & Link_student_subject
let rows_Students, rows_Subjects, rows_Link_Student_Subject;
// Create a Promise chain by
// executing two or more asynchronous operations back to back,
// where each subsequent operation starts when the previous operation succeeds,
// with the result from the previous step
Database.execute( config,
database => database.query( "select a.*, null as subjects from student a" )
.then( rows => {
rows_Students = rows;
return database.query( "select * from subject" )
} )
.then( rows => {
rows_Subjects = rows;
return database.query( "select * from link_student_subject" )
} )
.then( rows => {
rows_Link_Student_Subject = rows;
} )
).then( () => {
// Create your nested student JSON by looping on Students
// and inserting the corresponding Subjects array
for (let i = 0; i < rows_Students.length; i++) {
let arraySubjects = [];
for (let x = 0; x < rows_Link_Student_Subject.length; x++) {
if(rows_Students[i].id == rows_Link_Student_Subject[x].id_student){
arraySubjects.push(searchObjInArray(rows_Subjects, "id", rows_Link_Student_Subject[x].id_subject));
}
}
rows_Students[i].subjects = arraySubjects;
}
res.send(JSON.stringify(rows_Students));
} ).catch( err => {
// handle the error
res.send(err);
});
});
// Function - search if object in array has a value and return that object
function searchObjInArray(array, arrayProp, searchVal){
let result = null;
let obj = array.find((o, i) => {
if (o[arrayProp] == searchVal) {
result = array[i];
return true; // stop find function
}
});
return result;
}
If you run this code with node and go to "127.0.0.1/students" it will return exactly the same JSON as in your question.
All credits and extra info on MySQL and promises - https://codeburst.io/node-js-mysql-and-promises-4c3be599909b
MySQL 5.7+ has a JSON datatype that you can leverage for your "subjects" field. Here's a great tutorial on how to use that:
https://www.sitepoint.com/use-json-data-fields-mysql-databases/
I have a array of data something like
var records = [
{Name: '', Id: 1},
{Name: '', Id: 2},
{Name: '', Id: 3},
{Name: '', Id: 4},
{Name: '', Id: 5},
{Name: '', Id: 6}
];
there could be thousands of items inside records array...
Ques1: Can we create a stored procedure which will accept an array of objects in mysql?
Ques2: Is there a way to bulk insert this data into mysql with Node JS?
You can bulk insert the array of records ,but before that you might need to convert it into array of arrays
I use array reduce to get an array something like this
let j=[
{Name: '', Id: 1},
{Name: '', Id: 2},
{Name: '', Id: 3},
{Name: '', Id: 4},
{Name: '', Id: 5},
{Name: '', Id: 6}
];
let values=j.reduce((o,a)=>{
let ini=[];
ini.push(a.Name);
ini.push(a.Id);
o.push(ini);
return o
},[])
console.log(values);
This will output
[["",1],["",2],["",3],["",4],["",5],["",6]]
Now inserting into the mysql database
1-Using normal callback
const con=require('./mysql.js'); //mysql connectionin mysql.js
var sql = "INSERT INTO customers (name, id) VALUES ?";
con.query(sql, [values], function (err, result) { //pass values array (from above) directly here
if (err) throw err;
console.log("Number of records inserted: " + result.affectedRows);
});
});
so the format of multiple data insert should be like [[[a,b],[b,c],[d,k]]]
2-Using promises
var Promise = require("bluebird");//for promises
const promisecon=Promise.promisifyAll(require('./mysql.js'));//
var sql = "INSERT INTO customers (name, id) VALUES ?";
promisecon.queryAsync(sql,[values]).then((result)=>{//bluebird identifies with Async
console.log(result);
}).catch(function(err){
console.log(err);
})
3-Using async await
var sql = "INSERT INTO customers (name, id) VALUES ?";
async function build() {
try {
const result =await con.queryAsync(sql,[values]);
console.log(result);
} catch (err) {
// do something
}
}
build();