Sequelize Single Instance - Not working after Module.exports - javascript

I have this Sequelize Code for connecting to my database
var sequelize = new Sequelize('db-name', 'user', 'pwd', {
host: 'XXX.XX.XX.XXX',
dialect: 'mysql',
pool: {
max: 50,
min: 0,
idle: 1000000
},
});
I have wrapped this in a module like below
var express = require('express');
var app = module.exports = express();
var Sequelize = require('sequelize');
module.exports = function (Sequelize, DataTypes) {
return new Sequelize('db-name', 'user', 'pwd', {
host: 'XXX.XX.XX.XXX',
dialect: 'mysql',
pool: {
max: 50,
min: 0,
idle: 1000000
},
});
};
However ,when I call this code below:
var sequelize = require('../../Connection.js');
//load model
var City = sequelize.import('../../models/City.js');
It gives me an error saying - undefined is not a function.Basically it is not able to instantiate the sequelize object when I am importing the module
However everything works fine when I am putting these blocks in one page
My core requirement - I want a single connection object across my node app. I have modularized Express Routes in various page.

Your sequelize module exports a function, which returns sequelize. You have to actually call that function
var sequelize = require('../../Connection.js')() <-- ;
Remember to cache the instance in connection.js - otherwise you get a new connection each time. You can also export the instance directly:
module.exports = new Sequelize('db-name', 'user', 'pwd', {
host: 'XXX.XX.XX.XXX',
dialect: 'mysql',
pool: {
max: 50,
min: 0,
idle: 1000000
},
});

Related

Asynchronously load configuration for Sequelize CLI

I am using Sequelize CLI to run migrations against out database and I have the following .sequelizerc file
// .sequelizerc
const path = require('path');
module.exports = {
"config": path.resolve('src', 'database', 'config.js'),
"models-path": path.resolve('src', 'models'),
"seeders-path": path.resolve('src', 'database', 'seeders'),
"migrations-path": path.resolve('src', 'database', 'migrations'),
};
The credentials for our database are kept in a secrets manager so they can be easily rotated and never stored within our repository or someone's computer. Thus, our config.js file looks like:
// src/database/config.js
const { AsyncObtainDBCredentials } = require("../utilities");
async function setupDBCreds() {
const dbConfig = await AsyncObtainDBCredentials();
return dbConfig;
}
module.export = setupDBCreds(); // exports a promise and does not work
Sequelize CLI is expecting a configuration JSON like
const dotenv = require('dotenv')
dotenv.config()
const dbConfig = {
host: process.env.DB_HOST ?? 'localhost',
username: process.env.DB_USER ?? 'postgres',
port: process.env.DB_PORT ?? '5432',
database: process.env.DB_NAME ?? 'myDBName',
password: process.env.DB_PASSWORD ?? 'SuperSecretPasswd',
dialect: "postgres"
};
module.exports = dbConfig;
Is there a way to make this work so we can avoid users having write credentials in to an .env file?

Javascript class method returning undefined

I'm trying to return a value from a class but it's coming up undefined.
index.js
import DB from "./db.js"
import express from "express";
import cors from "cors";
const database = new DB();
app.get("/", (req, res) => {
const data = database.selectAllFromProducts();
console.log(data); // Returns undefined
});
app.listen(process.env.PORT, () =>
console.log(`Listening on Port ${process.env.PORT}`)
);
db.js
class DB {
constructor() {
this.connection = this.initialize();
}
initialize() {
return mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
selectAllFromProducts() {
this.initialize();
this.connection.query(`select * from ${process.env.DB_PRODUCTS_TABLE};`,
(err, results, fields) => {return results});
}
}
I have a front end that is sending the GET request and that is successful so it's not a routing problem. Console.logging the results works from db.js so I know it's not a MYSQL problem but for whatever reason it comes up blank in index.js. Thanks in advance for any help!
EDIT - I have module.exports = DB I just forgot to include it because I only included partial bits of the file. Importing works just fine for me because I'm using babel and type: module in my package.json. I couldn't tag node because it requires 1500 rep.
You forgot to export your module. Thus database should be undefined in your code, resulting in your issues.
class DB {
constructor() {
this.connection = this.initialize();
}
initialize() {
return mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
selectAllFromProducts() {
this.initialize();
this.connection.query(`select * from ${process.env.DB_PRODUCTS_TABLE};`,
(err, results, fields) => {return results});
}
}
module.exports = DB;
Also importing is a little different in node.js
var DB = require("./db.js");
var express = require("express");
var cors = require("cors");
const database = new DB();
app.get("/", (req, res) => {
const data = database.selectAllFromProducts();
console.log(data); // Returns undefined
});
app.listen(process.env.PORT, () =>
console.log(`Listening on Port ${process.env.PORT}`)
);
Note: You should be able to use javascript modules in node.js versions greater than 13 (which is why your code may be working). Make sure your deployment server supports node.js 13 as well if you decide to use that syntax. More on javascript modules

Knex leaves open server when using Jest (recommendation)

I'm trying to do some TDD with my following stack
Jest
Node
Koa2
SuperTest
Knex
Objection
My problem starts with the open handler of the koa server and I could solve that with the instance of the server and close it with server.close()
However, I have the same problem with knex; It leaves the server open and I have to run the knex.close to stop it. With that i can avoid the following error message
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't >stopped in your tests. Consider running Jest with --detectOpenHandles to >troubleshoot this issue.
knex.config
const config = {
development: {
client: 'pg',
connection: process.env.DATABASE_URL,
migrations:{
directory:"./migrations/"
},
pool: { min: 0, max: 7 }
},
test: {
client: 'pg',
connection: process.env.DATABASE_URL,
migrations:{
directory:"./migrations/"
},
pool: { min: 0, max: 7 }
},
//TBD
staging: {
client: 'postgresql',
connection: {
database: 'my_db',
user: 'username',
password: 'password'
},
pool: {
min: 2,
max: 10
},
migrations: {
tableName: 'knex_migrations'
}
},
//TBD
production: {
client: 'postgresql',
connection: {
database: 'my_db',
user: 'username',
password: 'password'
},
pool: {
min: 2,
max: 10
},
migrations: {
tableName: 'knex_migrations'
}
}
}
module.exports = config;
user.model.js
'use strict';
const knex = require('../config/db/knex');
const { Model } = require('objection');
Model.knex(knex);
class User extends Model {
// Table name is the only required property.
static get tableName() {
return 'user';
}
// Custom function to close knex
static close() {
knex.destroy();
}
}
module.exports = User;
user.test.js
const supertest = require('supertest');
const server = require('../../server');
var request = require("supertest").agent(server);
describe("Test users routes", () => {
let Model;
beforeAll(async () => {
// do something before anything else runs
console.log('Jest starting!');
Model = require('../../models/user.model')
});
// close the server after each test
afterAll(() => {
server.close();
Model.close();
console.log('server closed!');
});
test("Get /",async () => {
let res = await request.get('/users/');
expect(res.status).toBe(200);
});
});
I'm pretty sure it could be a better approach solution for what I did, maybe something related with the pool or some callback on the knex.cofing but I'm not sure.
Thank you

Trying to connect to SQL server using Tedious Connection and Windows Authentication?

I'm trying to connect to SQL server using tedious connection pool and windows authentication. But I get an error:
message: 'Login failed for user \'\'.', code: 'ELOGIN'
I'm not sure what I'm doing wrong. I'm using the latest version of tedious.
.env file
SQL_SERVER=localhost
SQL_UNAME=Username
SQL_PSWD=Password
SQL_DB=DatabaseName
SQL_DOMAIN=US
dbController.js
const {Request} = require('tedious');
const TYPES = require('tedious').TYPES;
const ConnectionPool = require('tedious-connection-pool');
const dbConfig = require('./dbconfig');
const poolConfig = {
min: 1,
max: 1,
log: true
};
let _rows = [];
const pool = new ConnectionPool(poolConfig, dbConfig);
pool.on('error', (err) => {
console.log(err);
});
dbConfig.js
const dotenv = require('dotenv');
dotenv.config();
module.exports = {
server: process.env.SQL_SERVER,
options: {
instanceName: 'SQLEXPRESS',
encrypt: false,
database: process.env.SQL_DB,
rowCollectionOnDone: true,
useColumnNames: true
},
authentication: {
type: 'ntlm',
options: {
userName: process.env.SQL_UNAME,
password: process.env.SQL_PSWD,
domain: process.env.SQL_DOMAIN
}
}
};
The problem is tedious-connection-pool is using tedious version 1 instead of tedious version 9.
I'm hoping to solve that with tedious-connection-pool2 based on a PR I found that never got merged upstream.
So, wait a day, and find my tedious-connection-pool2 and use the overrideTedious option that should work.

NodeJs With Mysql createPool and nodejs mysql wrapper module

i am using nodejs with mysql createPool and node-mysql-wrapper.
Link:
https://www.npmjs.com/package/node-mysql-wrapper
There is no option in the documentation to implement with module with myslq create pool. I tried it, but its not working. Here is my code:
var connection = mysql.createPool({
connectionLimit: 100,
host: 'localhost',
user: 'root',
password: '',
database: 'test'
});
var db = wrapper.wrap(connection);
db.ready(function(){
db.table("users").findById(8,function(user){
console.log(user);
});
});
As #Tajen Shrestha said. You need bind the wrapper with connection object. For e.g.:
var conObj = connection.getConnection.bind(connection);
var db = wrapper.wrap(conObj);
db.ready(function(){
db.table("users").findById(8,function(user){
console.log(user);
});
});

Categories