Skip to main content

Como criar uma Migration

Tutorial: Criando uma Migration no Laravel

Este tutorial demonstra o processo completo de criação de uma migration no Laravel utilizando como exemplo a tabela usuarios.

Ao final deste guia você será capaz de:

  • Criar uma migration;
  • Definir a conexão do banco utilizada;
  • Criar tabelas e colunas;
  • Definir chaves primárias;
  • Definir restrições de unicidade;
  • Utilizar enums;
  • Executar migrations;
  • Reverter migrations;
  • Compreender os tipos de colunas mais utilizados.

1. O que é uma Migration?

Uma migration é um arquivo PHP responsável por definir a estrutura do banco de dados.

Ela funciona como um controle de versão do banco.

Em vez de executar manualmente comandos SQL como:

CREATE TABLE usuarios (...);


o Laravel utiliza migrations:

Schema::create('usuarios', function (Blueprint $table) {
    ...
});


Isso permite que toda a equipe mantenha o banco sincronizado.


2. Criando uma Migration

Para criar uma migration:

php artisan make:migration create_usuarios_table


Será criado um arquivo semelhante a:

database/migrations/
└── 2026_06_10_144334_create_usuarios_table.php


Caso o projeto utilize uma pasta específica:

php artisan make:migration create_usuarios_table \
--path=database/migrations/selecao_prppg



3. Estrutura básica de uma Migration

Toda migration possui dois métodos:

public function up(): void
{
    // cria ou altera tabelas
}

public function down(): void
{
    // desfaz alterações
}



Método up()

Primeiro entramos no ouath-server:

docker exec -it oauth-server bash

Executado quando rodamos:

php artisan migrate --path=database/migrations/selecao_prppg/ --database=pgsql_selecao_prppg


Método down()

Executado quando queremos rever a última migration:

php artisan migrate:rollback --path=database/migrations/selecao_prppg/ --database=pgsql_selecao_prppg
Executado quando queremos reverter todas as migrations


php artisan migrate:fresh --path=database/migrations/selecao_prppg/ --database=pgsql_selecao_prppg



4. Definindo a conexão do banco

No projeto de vocês existe mais de uma conexão.

Por isso foi definido:

protected $connection = 'pgsql_selecao_prppg';


Isso indica que a migration será executada utilizando a conexão:

DB_CONNECTION=pgsql_selecao_prppg


configurada em:

config/database.php



5. Tratamento para ambiente de testes

No construtor:

public function __construct()
{
    if (app()->environment('testing')) {
        $this->connection = 'pgsql_testing';
    }
}


Quando os testes automatizados forem executados:

php artisan test


a migration utilizará:

pgsql_testing


em vez de:

pgsql_selecao_prppg


evitando alterações no banco real.


6. Verificando se a tabela já existe

Antes da criação:

if (!Schema::hasTable('usuarios'))


O Laravel verifica:

SELECT ...
FROM information_schema.tables


Se a tabela já existir:

usuarios


ela não será criada novamente.


7. Criando a tabela

A criação da tabela ocorre através de:

Schema::create('usuarios', function (Blueprint $table) {
    ...
});


Equivalente ao SQL:

CREATE TABLE usuarios (...);



8. Criando a chave primária

Código:

$table->id()
      ->autoIncrement()
      ->primary()
      ->comment('Id do Usuario');


Resultado:

id BIGINT PRIMARY KEY AUTO_INCREMENT


Observação:

No Laravel moderno geralmente basta:

$table->id();


pois o framework já cria:

  • auto increment
  • primary key

automaticamente.


9. Criando campos texto

Nome:

$table->string('nome', 100);


Resultado:

VARCHAR(100)



Email:

$table->string('email', 100);


Resultado:

VARCHAR(100)



CPF:

$table->string('cpf', 11);


Resultado:

VARCHAR(11)



10. Definindo valores únicos

Email:

$table->string('email', 100)->unique();


Resultado:

UNIQUE(email)


Não será possível cadastrar dois usuários com o mesmo email.


CPF:

$table->string('cpf', 11)->unique();


Resultado:

UNIQUE(cpf)



11. Trabalhando com datas

Campo:

$table->dateTime('data_cadastro');


Resultado:

DATETIME


ou

TIMESTAMP


dependendo do banco.

Exemplo:

2026-06-10 14:30:00



12. Trabalhando com Enum

Campo:

$table->enum('cargo', [
    'SECRETARIA',
    'COORDENADOR',
    'COMISSAO',
    'ADMINISTRADOR'
]);


Resultado:

ENUM(...)


Valores permitidos:

SECRETARIA
COORDENADOR
COMISSAO
ADMINISTRADOR


Qualquer outro valor será rejeitado.


13. Campo senha

Campo:

$table->string('senha', 60);


Resultado:

VARCHAR(60)


Normalmente armazenará um hash:

$2y$12$...


e não a senha em texto puro.


14. Timestamps automáticos

Código:

$table->timestamps();


Cria automaticamente:

created_at
updated_at


Exemplo:

Campo Função
created_at Data de criação
updated_at Última alteração

15. Executando a Migration

Após criar o arquivo:

php artisan migrate


O Laravel:

  1. Localiza migrations pendentes.
  2. Executa o método up().
  3. Registra a execução na tabela:
migrations



16. Verificando o status

php artisan migrate:status


Exemplo:

Migration name                     Ran?
-----------------------------------------
create_usuarios_table              Yes



17. Revertendo a Migration

Desfaz a última migration executada:

php artisan migrate:rollback


Executa:

public function down()
{
    Schema::dropIfExists('usuarios');
}



18. Recriando tudo

Muito utilizado durante desenvolvimento:

php artisan migrate:fresh


Apaga todas as tabelas e executa novamente todas as migrations.


Comandos mais utilizados

Comando Função
php artisan make:migration nome Criar migration
php artisan migrate Executar migrations
php artisan migrate:status Ver status
php artisan migrate:rollback Desfazer última migration
php artisan migrate:fresh Recriar banco
php artisan migrate --path=... Executar pasta específica

Tipos de colunas mais utilizados

Sintaxe Tipo SQL
$table->id() BIGINT PK
$table->string('nome') VARCHAR(255)
$table->string('nome',100) VARCHAR(100)
$table->text('descricao') TEXT
$table->integer('idade') INT
$table->bigInteger('codigo') BIGINT
$table->decimal('valor',10,2) DECIMAL
$table->boolean('ativo') BOOLEAN
$table->date('inicio') DATE
$table->dateTime('inicio') DATETIME
$table->timestamp('inicio') TIMESTAMP
$table->enum('status',[...]) ENUM
$table->json('dados') JSON

Modificadores mais utilizados

Sintaxe Função
->nullable() Permite NULL
->default('X') Valor padrão
->unique() Valor único
->comment('texto') Comentário da coluna
->index() Cria índice
->primary() Define PK
->autoIncrement() Auto incremento

Relacionamentos (Foreign Keys)

Os mais utilizados no projeto Guavira serão:

Forma moderna

$table->foreignId('programa_id')
      ->constrained('programas');


Com cascade

$table->foreignId('programa_id')
      ->constrained('programas')
      ->cascadeOnDelete();


Forma explícita

$table->unsignedBigInteger('programa_id');

$table->foreign('programa_id')
      ->references('id')
      ->on('programas');



Métodos mais utilizados no projeto

Ao criar as tabelas programas, editais, linhas_pesquisa, inscricoes, resultados e demais entidades do sistema, você utilizará principalmente:

Método Frequência
$table->id() Muito alta
$table->string() Muito alta
$table->foreignId() Muito alta
->constrained() Muito alta
$table->date() Alta
$table->enum() Alta
$table->timestamps() Muito alta
->nullable() Alta
->unique() Média
->cascadeOnDelete() Média

Esses métodos são suficientes para construir praticamente todas as tabelas do banco do sistema de seleção PRPPG/Guavira.

Caso Especial: Migration realizada em banco de dados incorreto

Por padrão, as migrations do sistema são registradas no banco da api (oauth-postgres), visto que ele precisa centralizar todas as tabelas da aplicação. Por esse motivo, pode ocorrer situações em que as migrations não ocorrem da maneira esperada visto que elas "já estão criadas".

Caso você queira reverter as migrations do seu banco, deve fazer o seguinte:

Acessar o container do seu banco, como por exemplo o selecao_prppg, entrar no psql e apagar o banco de dados atual, em sequência, você deve criar novamente o banco de dados, que desta vez estará em branco e livre para suportar novas migrations.

Em sequência, você deve acessar o banco de dados da api e verificar as migrations a partir do seguinte comando:

SELECT * FROM migrations

Como resultado, você terá acesso a todas as migrations registradas naquele banco, seu nome e seus id's. A partir dessa informação, devemos realizar o delete das migrations que iremos refazer, utilizando o comando:

DELETE FROM migrations WHERE id = (condição)

Em sequência, podemos realizar as migrations do sistema, que dessa vez não terão nenhum empecilho as impedindo e poderão ser recriadas do zero.