Code First Approach in Node Js !
Tags: node, sequelize, database, codefirst
Published: 2021-12-13 14:29:37

**Code First**- Approach prioritizing code over schema. Code First is a technique which helps us to create a database, migrates and maintaining the database and its tables from the code.

Sequelize is the package for code first. It can support many databases as well as MYSQL, MSQL and sqlLight. for that 

**Prerequisites**
To run sequelize , you should have few things installed on your system.

First we need to install sequelize package 

 `$ npm install --save sequelize`

Install sequelize cli

`$ npm install sequelize-cli -D`

Install database what you want 

`$ npm install --save mysql2 //sqlite,mssql`

Let's start by creating a our configuration file using:

`$ npx sequelize-cli init`

This will generate a few files for you, your project folder should now look like this:
`.
├── config
│   └── config.json
├── migrations
├── models
│   └── index.js
└── package.json`

Connect to the database


```
    const sequelize = new Sequelize('database', 'username', 
      'password', {
       host: 'localhost',
       dialect:mssql
   });
```

Test connection to the database
```
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
```

**Defining models**
Sequelize is all about the models in database language we can say these are our schemas- the structure that our data takes .Your models are the objects that you will interact with in your application and the primary tables that you will create and manage in your database.

**Create models for user table**

```
module.exports = (sequelize: any, DataTypes : any) => {
  class User extends Model<UserAttributes> 
  implements UserAttributes{
  
    Id!: number;
    FirstName!: string;
    static associate(models : any) {
      // define association here
      
    }
  };
  User.init({ 
    Id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      allowNull: false,
      primaryKey: true
    },
    FirstName: {
      type: DataTypes.STRING(20),
      allowNull: false
  }, {
    sequelize,
    modelName: 'User',
    freezeTableName:true
  });
  return User;
};
```
**Synchronizing Your Models**

The last step to set up Sequelize is to synchronize our models. We can sychronize individual tables by calling `.sync()` on the table.
For example, `user.sync()` or `role.sync()`. To sync the whole database, just use `db.sync()`.
When testing, it's sometimes easier to start with fresh tables every time you launch your application. `.sync()` can take an object with parameters that allow you to control various aspects of database synchronization. One of these is {force: true}.
`db.sync({force: true})` will drop your tables, and resync your data as though you are starting new.

```
db.sequelize.sync({ force: true }).then(() => {
    app.listen(port, () => {
        console.log("Drop and re-sync DB");
    })
});
```
 force: true will drop the table if it already exists


**Migrations**

The name of migration file is it will have the timestamp of when the migration file was created. This reason  is sequelize can run the older migration files first, and then the newer ones that build on top of them. This is useful  when changes need to be made to the database.
Also, make sure  that your models and your migrations match. The migration files keep track of the state of the database schemas, and should always be created when changes to your models are made. Always commit corresponding migration files when changes to your models are made.
```
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('user', {
 
//write code here 

  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable('user');
  },
};
```

 Lets consider you forgot to add  Email column in user Table no worry’s sequelize migrations has an addColumn function that will fix the problem 
`sequelize migration:create --name add-email-to-user`

this command only generates migration file so you have to add some code in up and down functions
 ```
'use strict';

module.exports = {
  up: function (queryInterface, Sequelize) {
    return queryInterface.addColumn( 'user', 'email', Sequelize.STRING );
  },

  down: function (queryInterface, Sequelize) {
    return queryInterface.removeColumn( 'user', 'email' );
  }
};
```

Every time you run `sequelize db:migrate` it will call the up method. And if you ever want to revert backwards, you can call `sequelize db:migrate:undo` which will call the down method. They should always be opposite actions, this allows you to safely run migrations and know that the state of the database will be intact.