Criando as Migrations Capítulo ensinando como criar as primeiras migrations da aplicação. 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 usuario . 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: Localiza migrations pendentes. Executa o método up() . 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.