Query a Google cloud SQL instance in Node.js from a GKE pod with cloud sql proxy running as sidecar - mysql

I am tasked with adding a MySql database to a microservice application for work. I am the only person on this task and don't really have anyone to turn too for advice so I am reaching out to the internets for help. I have succesfully deployed a pod that is running a small test application and the cloud-sql-proxy. I have scoured the documentation trying to figure out how to connect to the db and perform a query and this is what I have come up with (but it doesn't work).
const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser')
const cors = require('cors');
const axios = require('axios');
const app = express();
app.use(bodyParser.json());
app.use(cors())
app.enable('trust proxy');
// Automatically parse request body as form data.
app.use(express.urlencoded({extended: false}));
// This middleware is available in Express v4.16.0 onwards
app.use(express.json());
// [START cloud_sql_mysql_mysql_create_tcp]
const createTcpPool = async config => {
// Extract host and port from socket address
const dbSocketAddr = process.env.DB_HOST.split(':');
// Establish a connection to the database
return mysql.createPool({
user: process.env.DB_USER, // e.g. 'my-db-user'
password: process.env.DB_PASS, // e.g. 'my-db-password'
database: process.env.DB_NAME, // e.g. 'my-database'
host: dbSocketAddr[0], // e.g. '127.0.0.1'
port: dbSocketAddr[1], // e.g. '3306'
// ... Specify additional properties here.
...config,
});
};
// [END cloud_sql_mysql_mysql_create_tcp]
var pool = createTcpPool();
const stuff = pool.query('SELECT * FROM entries');
function getQuery() {
console.log(stuff);
}
getQuery()
Here is a picture of the error I get when I deploy the pod and the logs from the proxy to verify it's running
I'm pretty new to MySql and GKE and trying to figure this out has been a huge struggle. I just want to know how I can actually query the db and would greatly appreciate some assistance or code sample to point me in the right direction, thanks internets.

As mentioned in the thread1 ,
Handling such functions can be done through following example :
const mysql = require('mysql');
const pool = mysql.createPool({ connectionLimit : 1, socketPath: '/cloudsql/' + '$PROJECT_ID:$REGION:$SPANNER_INSTANCE_NAME',
user: '$USER', p
assword: '$PASS',
database: '$DATABASE' });
exports.handler = function handler(req, res)
{ //using pool instead of creating connection with function call
pool.query(`SELECT * FROM table where id = ?`,
req.body.id, function (e, results) {
//made reply here
}); };
For more information you can refer to the documentation related to TCP connection when using Node js.
const createTcpPool = async config => {
// Extract host and port from socket address
const dbSocketAddr = process.env.DB_HOST.split(':');
// Establish a connection to the database
return mysql.createPool({
user: process.env.DB_USER, // e.g. 'my-db-user'
password: process.env.DB_PASS, // e.g. 'my-db-password'
database: process.env.DB_NAME, // e.g. 'my-database'
host: dbSocketAddr[0], // e.g. '127.0.0.1'
port: dbSocketAddr[1], // e.g. '3306'
// ... Specify additional properties here.
...config,
});
};

So trying to create a pool by calling createTcpPool seems to have been the issue. I changed it to
let pool = mysql.createPool({
user: process.env.DB_USER, // e.g. 'my-db-user'
password: process.env.DB_PASS, // e.g. 'my-db-password'
database: process.env.DB_NAME, // e.g. 'my-database'
host: '127.0.0.1', // e.g. '127.0.0.1'
port: '3306'
});
and got a succesful return from my db.

Related

pool.querty is not a function. Trying to connect google-cloud mysql instance from local machine

When trying to connect to the mysql instance on gcloud using nodejs and express. I'm getting the error "pool.query" is not a function. Bear with me since this the first time using gcloud and nodejs, i may be missing something obvious. I have already authorized my local ip,
This is my config
const config = {
user: process.env.DB_USER, // e.g. 'my-db-user'
password: process.env.DB_PASS, // e.g. 'my-db-password'
database: process.env.DB_NAME, // e.g. 'my-database'
socketPath: '/cloudsql/'+ process.env.INSTANCE_UNIX_SOCKET, // e.g. '/cloudsql/project:region:instance'
connectionLimit: 5,
connectTimeout: 10000, // 10 seconds
waitForConnections: true, // Default: true
queueLimit: 0, // Default: 0
};
module.exports = config;
This is my pool creation method
//dotenv
require('dotenv').config();
// import mysql2
const mysql = require('mysql2/promise');
// get config
const config = require("./config");
// Connect to database
// createUnixSocketPool initializes a Unix socket connection pool for
// a Cloud SQL instance of MySQL.
async function createUnixSocketPool() {
return mysql.createPool({...config,});
};
module.exports = {createUnixSocketPool};
And lastly my code for connecting
const path = require('path');
const express = require('express');
const { createUnixSocketPool } = require("./db");
const app = express();
// create mysql pool
const pool = createUnixSocketPool();
app.get('/',async (req,res) => {
console.log(await pool.query("show tables;"));
res.send("test");
});
// Listening
const PORT = process.env.PORT || 3000
app.listen(PORT, () => console.log('App is listening on port '+ PORT));
For some reason this says that pool.query doesn't exist? I'm very new to node.js and javascript in general, what am i missing?

Dynamically change the name of mySql database in pool in node.js

connection.js
var mysql = require("mysql");
const { createPool } = require("mysql");
const pool = createPool({
port: process.env.DB_PORT,
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.MYSQL_DB,
connectionLimit: 10,
});
module.exports = pool;
product.service.js
const pool = require("../../../config/database");
module.exports = {
viewVariate: (callBack) => {
pool.query(
`SELECT varId , varName FROM variations WHERE varIsActive='1'`,
(errors, results, fields) => {
if (errors) {
return callBack(errors);
}
return callBack(null, results);
}
);
},
}
I have to maintain more than 100 users. so each person has own database in that node app. each person database name call via API , so I need to set given database name to above pool dynamically , I referred may ways. it did not work. connection.js file is my database connection with pool. then it call to service files to make connection queries. for that pool data obtains form env file. it doesn't matter when config mentioned requirement will be done.

mysql2/promise require database connection file

I have only been working with PHP before going to Node.JS. What I was able to do in PHP when working with MYSQL was that I could include the database.php file in the files I wanted to execure queries in.
It doesn't seem to be the same in Node.Js. This is my database.js file
const mysql = require("mysql2/promise");
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'XXXX',
database: 'nodelogin'
});
module.exports = db;
Then I require this in my file login.js
const db = require("../../database");
However, when I then try to run db.query(sql, [variable]) I get db.query is not a function.
Why is this? It shouldn't be that more complicated or should it?
If you use a connection pool instead, you can include the pool once, then call query on it, like so:
db-config.js
const mysql = require("mysql2/promise");
console.log("Creating connection pool...")
const pool = mysql.createPool({
host: 'localhost',
user: 'user',
database: 'test_db',
password: 'password'
})
module.exports = pool;
test.js
// Require to whereever db-config is
const pool = require('./db-config.js');
async function testQuery() {
const results = await pool.query("select * from users");
console.table(results[0]);
}
testQuery();

Nodejs - unable to load environment variable in mysql2

I am using the mysql2 package for connecting node with MySQL and I am using a .env file to store my username and password. But when I use it in my config for connecting MySql it doesn't load. It throws the following error whenever I hit an endpoint using Postman.
Error: Access denied for user 'undefined'#'localhost' (using password: YES)
Below is my code:
const express = require("express");
const router = express.Router();
const mysql = require("mysql2");
const connection = mysql.createPool({
user: `${process.env.DB_USERNAME}`,
host: "localhost",
password: `${process.env.DB_PASSWORD}`,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
database: "issue",
});
I am using dotenv to load env variables and initialized in my entry file as:
require('dotenv').config();
What am I doing wrong?
As a side effect of the way JavaScript coerces types, process.env.foo will result in "undefined" if it is undefined and used in a string.
There is either a typo in your dotenv config file or else some other problem with your use of dotenv.
I would recommend more defensive coding to give a better error message when this happens. (The following code is untested, but you will no doubt get the idea.)
const express = require("express");
const router = express.Router();
const mysql = require("mysql2");
const dbUsername = process.env.DB_USERNAME;
const dbPassword = process.env.DB_PASSWORD;
if (!dbUsername) {
throw new Error('DB_USERNAME environment variables must be set');
}
if (!dbPassword) {
throw new Error('DB_PASSWORD environment variables must be set');
}
const connection = mysql.createPool({
user: dbUsername,
host: "localhost",
password: dbPassword,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
database: "issue",
});

Connect Sequelize/Node to XAMPP Mysql

I've a working script to connect and work with Sequelize on Node.js
But now i'm trying to connect this to my MySQL database on XAMPP
MySQL Port on XAMPP: 3306
When i run node.js after i have configured the app.listen and the config of sequealize i get the following error
ERROR: listen EADDRINUSE :::3306
I've looked for but i didn't find much information about that, i don't know what i'm doing bad.
Thanks you for every answer!
app.js
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const morgan = require('morgan')
const { sequelize } = require('./models')
const config = require('./config/config')
const app = express()
app.use(morgan('combined'))
app.use(bodyParser.json())
app.use(cors())
require('./routes')(app)
sequelize.sync()
.then(() => {
app.listen(config.db.options.port || 3306) // 8081 original
console.log(`Server iniciado en puerto: ${config.db.options.port}`)
})
config.js
module.exports = {
db: {
database: process.env.DB_NAME || 'intraenvios',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASS || '',
options: {
dialect: process.env.DIALECT || 'mysql', // sqlite original
host: process.env.HOST || 'localhost',
storage: './intraenvios.sqlite',
port: process.env.PORT || 3306 // 8081 original
}
}
}
EDIT:
For to connect by xampp simply, i made this:
const sequelize = new Sequelize('test', 'root', '', {
host: "127.0.0.1",
dialect : 'mysql',
operatorsAliases: false
});
sequelize.authenticate().then(function(){
console.log("sucess");
}).catch(function(error){
console.log("error: "+error);
});
Obs: operatorsAliases: false - To fix deprecated message of sequelize
Good Fun :)