difference between Tedious and sequelize - node.js

i am new in Backend, i started learning node, i found the ORM sequelize and it's a good to handle with database but also find tedious . i did not understand the relation between them , can i use sequelize only in my project without tedious ? i found lot of people work with the two but i did not understqand why , i mean if we can use sequelize and interact with db why we have to use tedious at the same time ?
var Connection = require('tedious').Connection;
var config = {
server: "192.168.1.210",
options: {},
authentication: {
type: "default",
options: {
userName: "test",
password: "test",
}
}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
if(err) {
console.log('Error: ', err)
}
// If no error, then good to go...
executeStatement();
});
const Sequelize = require('sequelize')
module.exports = new Sequelize('db', 'user', 'password', {
host: '',
dialect: 'mssql',
pool: {
max: 50,
min: 2,
idle: 10000
},
});

Ofcourse you can work with only sequelize. As I can see in the documentation.
Tedious is a pure-Javascript implementation of the TDS protocol, which is used to interact with instances of Microsoft's SQL Server. It is intended to be a fairly slim implementation of the protocol, with not too much additional functionality.
But sequelize will work will all db.
Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more.

Related

Sync Sequelize Databases on Serverless app

I am using sequelize with MySQL on the Serverless offline app.
I am not sure how to sync all models on serverless start?
I am tried to do this
import Sequelize from "sequelize";
import mysql2 from 'mysql2';
const sequelize = new Sequelize('database', 'root', '', {
dialect: 'mysql',
dialectModule: mysql2,
host: 'localhost',
});
const getSequelize = () => {
sequelize.sync({ force: false })
.then(() => {
console.log(`Database & tables synchronised!`)
});
return sequelize;
}
export default getSequelize();
This approach syncs models that are imported into controller, so the only way in this case to sync all models is to include all models in every controller.
This does not look like a good example.
Do you have any idea?
Use sequelize.sync only for development purposes. Use sequelize migrations for production.
There must be some way to run console command db:migrate in your environment. When you push all the migration code use that command to update your database to the last version.

Can Sequelize be used to connect to a new database?

In designing a simple node.js project, I tried using Sequelize to connect to a mysql server using the following configuration parameters:
{ dbname: users
username: jimmy
password: users
params:
host: localhost
port: 3306
dialect: mysql }
though the 'users' database didn't exist yet.
I got a server error:
InternalServerError: {"name":"SequelizeConnectionError","parent":{"code":"ER_BAD_DB_ERROR","errno":1049,"sqlState":"42000","sqlMessage":"Unknown database 'users'"},"original":{"code":"ER_BAD_DB_ERROR","errno":1049,"sqlState":"42000","sqlMessage":"Unknown database 'users'"}}
But the Sequelize docs: Manual | Sequelize indicate that Sequelize can connect to a new database. Please, how can Sequelize be used to connect to a
new(non-existing) database?
You should read the documentation again carefully (because the wording is indeed confusing!).
New databases versus existing databases
If you are starting a project from scratch, and your database does not exist yet, Sequelize
can be used since the beginning in order to automate the creation of
every table in your database.
Also, if you want to use Sequelize to connect to a database that is
already filled with tables and data, that works as well! Sequelize has
got you covered in both cases.
It will connect only to an existing DB, it can help you by creating the tables if they do not exist yet but the DB has to be there in order for sequelize to connect with it.
Following this question, I wrote this PR to update the documentation to be less confusing. Hope it help!
Found a similar problem on SO, and an answer by osifo:
//create the sequelize instance omitting the database-name arg
const sequelize = new Sequelize("", "<db_user>", "<db_password>", {
dialect: "<dialect>"
});
return sequelize.query("CREATE DATABASE `<database_name>`;").then(data
=> {
// code to run after successful creation.
});
So, I was able to implement it in my own code:
var SQUser;
var sequlz;
async function connectDB() {
sequlz =
new Sequelize("", "jimmy", "users", {host: "localhost", port: 3306, dialect: "mysql"});
await sequlz.query("CREATE DATABASE users;");
await sequlz.query("Use users;");
SQUser = sequlz.define('Table',
{
// define table schema
});
return SQUser.sync();
};
//use sequelize to populate the table
async function create() {
const SQUser = await connectDB();
return SQUser.create(
//values
);
}

Login failed using Express and Sequelize with SQL Server

I am trying to use Sequelize (v 5.21.13) to connect to my SQL Server database in my Expressjs app.
dbconfig.js
var dbConfig = {
server: process.env.DB_HOST,
authentication: {
type: 'default',
options: {
userName: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD
}
},
options: {
database: process.env.DB_NAME
}
};
module.exports = dbConfig;
index.js:
const dbConfig = require('./dbConfig');
const Sequelize = require('sequelize');
const connection = new Sequelize(
dbConfig.options.database,
dbConfig.authentication.options.userName,
dbConfig.authentication.options.password,
{
host: dbConfig.server,
dialect: 'mssql',
}
);
connection.sync().then(() => {
console.log('Connected!');
}).catch((e) => {
console.log('Error:\n', e);
});
Now the thing is that each time I run the server, I get this error
AccessDeniedError [SequelizeAccessDeniedError]: Login failed for user 'master'.
I have also tried adding additional properties to the new Sequelize() like the following with no luck.
dialectOptions: {
instanceName: 'instance',
options: {
encrypt: true,
trustServerCertificate: true,
requestTimeout: 30000
}
}
I even tried changing the password to a very simple one with no special characters, connection with Datagrip works after changing but not using Sequelize.
Everything on the dbconfig object is correct so I don't see what the issue might be.
Solved it. I was putting the the db instance id as the database name, I realized that the database name was different. Changed it and I'm now connected through Sequelize.

Automated Testing with Databases

I'm fairly new to automated testing and was wondering how I should go about writing tests for the database. The project I'm working on right now is running PostgreSQL with Sequelize as the ORM on a Node.JS environment. If it matters, I'm also using Jest as the testing library right now.
In my app I use a config module to control configuration settings for different environments. When running tests the process.env.APP_ENV is set to test, and it will set the dialect to sqlite. Note that you will not have any data or data persistence, so you will need to populate it with all the data needed for your tests.
Include sqlite3
yarn add -D sqlite3
or
npm i -D sqlite3
Config
module.exports = {
database: {
name: 'dbname',
user: 'user',
password: 'password',
host: 'host',
// Use "sqlite" for "test", the connection settings above are ignored
dialect: process.env.APP_ENV === 'test' ? 'sqlite' : 'mysql',
},
};
Database/Sequelize
// get our config
const config = require('../config');
// ... code
const instance = new Sequelize(
config.database.name,
config.database.user,
config.database.password,
{
host: config.database.host,
// set the dialect, will be "sqlite" for "test"
dialect: config.database.dialect,
}
);
Test Class (Mocha)
const TestUtils = require('./lib/test-utils');
describe('Some Tests', () => {
let app = null;
// run before the tests start
before((done) => {
// Mock up our services
TestUtils.mock();
// these are instantiated after the mocking
app = require('../server');
// Populate redis data
TestUtils.populateRedis(() => {
// Populate db data
TestUtils.syncAndPopulateDatabase('test-data', () => {
done();
});
});
});
// run code after tests have completed
after(() => {
TestUtils.unMock();
});
describe('/my/route', () => {
it('should do something', (done) => {
return done();
});
});
});
Run Tests
APP_ENV=test ./node_modules/.bin/mocha
You could use ENV variables in other ways to set the dialect and connection parameters as well - the above is just an example based on what we have done with a lot of supporting code.
If you're not doing anything particularly complicated on the DB side, take a look at pg-mem:
https://swizec.com/blog/pg-mem-and-jest-for-smooth-integration-testing/
https://github.com/oguimbal/pg-mem
It's really cool in that it tests actual PG syntax and can pick up a bunch of errors that using a different DB or mock DB won't pick up. However, it's not a perfect implementation and missing a bunch of features (e.g. triggers, decent "not exists" handling, lots of functions) some of which are easy to work around with the hooks provided and some aren't.
For me, having the test DB initialized with the same schema initialization scripts as the real DB is a big win.

My Node.js local application won't connect to Azure SQL DB

I am developing a Node.js-Express-EJS web application, with Azure SQL DB (cloud version of MS SQL Server).
I try to test my connection first on the remote Azure SQL DB, using SQL Server Management Studio. First, I set my machine's IP to be allowed in Azure SQL DB firewall rules. Then I was able to get into the database, create and populate table, and query using the Management Studio.
Now, I have the Node.js app locally first. However, it seems it can't connect to the remote Azure SQL DB using same credentials.
First, I use the tutorial in node-mssql:
/* Using node-mssql */
var sql = require('mssql');
router.get('/test/mssql', function(req, res, next) {
console.log('Testing node-mssql')
sql.connect("mssql://<username>:<password>#<server>.database.windows.net/<db>")
.then(function() {
new sql.Request()
.query('SELECT * FROM mytable')
.then(function(recordset) {
console.dir(recordset);
}).catch(function(err) {
console.log(err);
});
}).catch(function(err) {
console.log(err);
});
});
I was only able to get from the console
'Testing node-mssql'
GET /contact/test/mssql - - ms - -
But no response, it seems its waiting forever, it didn't even throw error.
Same thing happens when I use Sequelize.js
/* Using Sequelize.js */
var Sequelize = require('sequelize');
var sequelize = new Sequelize('<db>', '<username>', '<password>', {
host: '<mydb>.database.windows.net',
dialect: 'mssql',
pool: {
max: 5,
min: 0,
idle: 10000
},
});
router.get('/test/sequelize', function(req, res, next) {
console.log('Testing sequelize');
sequelize.authenticate()
.then(function(err) {
console.log('Connection has been established successfully');
})
.catch(function(err) {
console.log('Unable to connect to the database:', err);
});
});
Result:
Testing sequelize
GET /test/sequelize - - ms - -
Here are the versions that I am using:
Node.js - 4.6.0
express - 4.14.0
mssql - 3.3.0
sequelize - 3.30.2
tedious - 1.14.0
(I wonder if this has to do with me connected on WiFi? But impossible, bec. Management Studio works fine right?)
If you're trying it out with Azure SQL Database, you'd need to add ?encrypt=true to your connection string that will look like:
mssql://<username>:<password>#<server>.database.windows.net/<db>?encrypt=true
For Sequelize.js, you'd need this: dialectOptions: { encrypt: true }. The code will look like:
var sequelize = new Sequelize('<db>', '<username>', '<password>', {
host: '<mydb>.database.windows.net',
dialect: 'mssql',
// Use this if you're on Windows Azure
dialectOptions: {
encrypt: true
},
pool: {
max: 5,
min: 0,
idle: 10000
},
});
I think the issue is with your connection string, as that doesn't look like a SQL Database connection string that would work.
For mssql, try connecting like this:
var config = {
server: "<servername>.database.windows.net",
database: "<dbname>",
user: "<username>",
password: "<password>",
port: 1433,
options: {
encrypt: true
}
};
sql.connect(config).then(function() { ... } )
FYI for reference, SQL Database (at least through .net) expects a connection string like this, so you might have success with a similar connection string directly passed to sql.connect() (though I haven't tried it):
Server=tcp:[serverName].database.windows.net;Database=myDataBase;
User ID=[LoginForDb]#[serverName];Password=myPassword;Trusted_Connection=False;
Encrypt=True;

Resources