Migrations com TypeORM no NodeJs
Tags: node, typeorm, migrations
Published: 2020-09-13 17:59:40

Essa postagem tem como objetivo apresentar como criar **migrations** em aplicações **NodeJs**, para a criação vamos usar o **ORM TypeORM**.

* **ORM(Object Relational Mapper)**: é uma técnica de mapeamento objeto relacional que permite fazer uma relação dos objetos com os dados que os mesmos representam;

* **TypeORM** é um **ORM** que pode ser executado em plataforma **NodeJs**, **Browser**, **React Native**, **TypeScript**, **JavaScript** entre outros, no nosso exemplo vamos configurar um projeto para poder usá-lo para criar e interagir com dados das tabelas;

##**1 – Adicionar pacotes**

Com o projeto já criado vamos começar a adicionar os pacotes necessários, execute os comandos a seguir:

**a) TypeORM**

```javascript
yarn add typeorm
yarn add reflect-metadata
```
**b) Postgres**

```javascript
yarn add pg
```
**c) ts-node**

```javascript
yarn add -D ts-node-dev
yarn add -D tsconfig-paths
```

##**2 – Script Package**

Para executar o comando **typeorm** vamos criar o trecho do **script**, adicione o trecho de código no **package.json**:

```javascript
"scripts": {
    "dev:server": "ts-node-dev -r tsconfig-paths/register  --inspect --transpile-only --ignore-watch node_modules src/server.ts",
    "start": "ts-node src/server.ts",
    "typeorm": "ts-node-dev -r tsconfig-paths/register ./node_modules/typeorm/cli.js"
  },
```

##**3 – Configuração ORM**

Para poder criar e acessar a base de dados temos que criar as configurações, para isso crie na raiz do projeto o arquivo **ormconfig.json**.

No arquivo **ormconfig.json** coloque o código abaixo:

```javascript
[{
  "name": "default",
  "type": "postgres",
  "host": "localhost",
  "port": 5432,
  "username": "postgres",
  "password": "docker",
  "database": "baseOrm",
  "entities": ["./src/models/**/*.ts"],
  "migrations": ["./src/migrations/*.ts"],
  "cli": {
    "migrationsDir": "./src/migrations/"
  }
}]
```

* **type**:  Tipo de base de dados que pode ser: **mysql**, **postgres**, **cockroachdb**, **mariadb**, **sqlite**, **better-sqlite3**, **cordova**, **nativescript**, **oracle**, **mssql**, **mongodb**, **sqljs**, **react-native**;
* **host**: Se for usar acesso a banco de dados remoto ou uma **VM**, utilize o **IP**;
* **port**: porta de acesso ao banco de dados;
* **username**: usuário com acesso ao banco de dados;
* **password**: senha de acesso ao banco de dados;
* **database**: nome da base de dados;
* **entities**: local onde vamos criar nossas entidades, essas entidades são as que vamos mapear;
* **migrations**: informa o local onde nossas **migrations** são carregadas;
* migrationsDir: local onde as migrations devem ser criada pelo CLI;

##**4 – Entidades**

Para exemplificar vou criar duas entidades com relacionamento **one-to-one** são elas: **Profile** e **User**.

**a) profile.ts**

```javascript
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity("profiles")
export default class Profile {
  @PrimaryGeneratedColumn("uuid")
  id: string;

  @Column()
  gender: string;

  @Column()
  photo: string;
}
```
**b) user.ts**

```javascript
import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  OneToOne,
  JoinColumn
} from "typeorm";
import Profile from "./profile";

@Entity("users")
export default class User {
  @PrimaryGeneratedColumn("uuid")
  id: string;

  @Column()
  name: string;

  @Column()
  profile_id: string;

  @OneToOne(type => Profile)
  @JoinColumn({ name: "profile_id" })
  profile: Profile;
}
```
Como pode ser observado temos duas entidades: **user.ts** que possui **profile.ts**.

##**5 – TypeORM CLI**

Depois de adicionar os pacotes, configuração os dados de acesso ao banco de dados e criar nossas entidades agora é hora de executar o comando para criar as tabelas.

**a) Criar migrations**

```javascript
yarn typeorm migration:create -n CreateProfile
yarn typeorm migration:create -n CreateUser
```

##**6 – Migrations**

Após executar o passo acima será criados as **migrations**, temos que adicionar os códigos que vão criar as tabelas, segue abaixo:

**a) Migration Profile**

```javascript
import { MigrationInterface, QueryRunner, Table } from "typeorm";

export default class CreateProfile1600016576988 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.createTable(
      new Table({
        name: "profiles",
        columns: [
          {
            name: "id",
            type: "uuid",
            isPrimary: true,
            generationStrategy: "uuid",
            default: "uuid_generate_v4()"
          },
          {
            name: "gender",
            type: "varchar(200)"
          },
          {
            name: "photo",
            type: "varchar(200)"
          }
        ]
      })
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.dropTable("profiles");
  }
}
```

**b) Migration User**

```javascript
import { MigrationInterface, QueryRunner, Table } from "typeorm";

export default class CreateUser1600016590838 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.createTable(
      new Table({
        name: "users",
        columns: [
          {
            name: "id",
            type: "uuid",
            isPrimary: true,
            generationStrategy: "uuid",
            default: "uuid_generate_v4()"
          },
          {
            name: "name",
            type: "varchar(200)"
          },
          {
            name: "profile_id",
            type: "uuid"
          }
        ],
        foreignKeys: [
          {
            name: "providerUser",
            referencedTableName: "profiles",
            referencedColumnNames: ["id"],
            columnNames: ["profile_id"],
            onDelete: "CASCADE",
            onUpdate: "CASCADE"
          }
        ]
      })
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.dropTable("users");
  }
}
```

Após criar as **migrations** vamos executar o comando para rodar as **migrations** e criar as tabelas:

```javascript
yarn typeorm migration:run
```

Se tudo ocorre sem erro será criado as tabelas na base de dados igual segue a imagem abaixo:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cqar1h5e5wtt1fp0ul3s.png)

Caso queira reverter a criação das tabelas pode ser executado o comando:

```javascript
yarn typeorm migration:revert
```

[Código completo GitHub](https://github.com/wandealves/migrations_nodejs)