- Introducción
- Generación de Migraciones
- Estructura de la Migración
- Ejecución de Migraciones
- Tablas
- Columnas
- Índices
- Eventos
#Introducción
Las migraciones son como el control de versiones para su base de datos, permitiendo que su equipo defina y comparta la definición del esquema de la base de datos de la aplicación. Si alguna vez ha tenido que decirle a un compañero que agregue manualmente una columna a su esquema local de base de datos después de incorporar sus cambios desde el control de código, ha enfrentado el problema que las migraciones de base de datos resuelven.
El facade Schema de Laravel proporciona soporte independiente de la base de datos para crear y manipular tablas en todos los sistemas de base de datos soportados por Laravel. Normalmente, las migraciones usarán este facade para crear y modificar tablas y columnas de la base de datos.
#Generación de Migraciones
Puede usar el comando Artisan make:migration para generar una migración de base de datos. La nueva migración se colocará en el directorio database/migrations. Cada nombre de archivo de migración contiene una marca de tiempo que permite a Laravel determinar el orden de las migraciones:
php artisan make:migration create_flights_table
Laravel usará el nombre de la migración para intentar adivinar el nombre de la tabla y si la migración creará una tabla nueva o no. Si Laravel puede determinar el nombre de la tabla a partir del nombre de la migración, prellenará el archivo de migración generado con la tabla especificada. De lo contrario, puede especificar la tabla manualmente en el archivo de migración.
Si desea especificar una ruta personalizada para la migración generada, puede usar la opción --path al ejecutar el comando make:migration. La ruta dada debe ser relativa a la ruta base de su aplicación.
Los stubs de migración pueden personalizarse usando la publicación de stubs.
#Consolidación de Migraciones
A medida que construye su aplicación, puede acumular más y más migraciones con el tiempo. Esto puede hacer que su directorio database/migrations se llene con potencialmente cientos de migraciones. Si lo desea, puede "consolidar" sus migraciones en un solo archivo SQL. Para comenzar, ejecute el comando schema:dump:
php artisan schema:dump
# Volcar el esquema actual de la base de datos y eliminar todas las migraciones existentes...
php artisan schema:dump --prune
Cuando ejecute este comando, Laravel escribirá un archivo de "esquema" en el directorio database/schema de su aplicación. El nombre del archivo de esquema corresponderá a la conexión de base de datos. Ahora, cuando intente migrar su base de datos y no se hayan ejecutado otras migraciones, Laravel ejecutará primero las sentencias SQL en el archivo de esquema de la conexión de base de datos que está usando. Después de ejecutar las sentencias SQL del archivo de esquema, Laravel ejecutará cualquier migración restante que no formara parte del volcado del esquema.
Si las pruebas de su aplicación usan una conexión de base de datos diferente a la que normalmente usa durante el desarrollo local, debe asegurarse de haber volcado un archivo de esquema usando esa conexión de base de datos para que sus pruebas puedan construir su base de datos. Puede hacer esto después de volcar la conexión de base de datos que normalmente usa durante el desarrollo local:
php artisan schema:dump
php artisan schema:dump --database=testing --prune
Debe comprometer su archivo de esquema de base de datos en el control de código para que otros desarrolladores nuevos en su equipo puedan crear rápidamente la estructura inicial de la base de datos de su aplicación.
La consolidación de migraciones solo está disponible para las bases de datos MySQL, PostgreSQL y SQLite y utiliza el cliente de línea de comandos de la base de datos.
#Estructura de la Migración
Una clase de migración contiene dos métodos: up y down. El método up se usa para agregar nuevas tablas, columnas o índices a su base de datos, mientras que el método down debe revertir las operaciones realizadas por el método up.
Dentro de ambos métodos, puede usar el constructor de esquemas de Laravel para crear y modificar tablas de forma expresiva. Para conocer todos los métodos disponibles en el constructor Schema, consulte su documentación. Por ejemplo, la siguiente migración crea una tabla flights:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Ejecutar las migraciones.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
/**
* Revertir las migraciones.
*/
public function down(): void
{
Schema::drop('flights');
}
};
#Configuración de la Conexión de la Migración
Si su migración interactuará con una conexión de base de datos distinta a la conexión predeterminada de su aplicación, debe establecer la propiedad $connection de su migración:
/**
* La conexión de base de datos que debe usar la migración.
*
* @var string
*/
protected $connection = 'pgsql';
/**
* Ejecutar las migraciones.
*/
public function up(): void
{
// ...
}
#Ejecución de Migraciones
Para ejecutar todas sus migraciones pendientes, ejecute el comando Artisan migrate:
php artisan migrate
Si desea ver qué migraciones se han ejecutado hasta ahora, puede usar el comando Artisan migrate:status:
php artisan migrate:status
Si desea ver las sentencias SQL que se ejecutarán con las migraciones sin ejecutarlas realmente, puede usar la opción --pretend con el comando migrate:
php artisan migrate --pretend
#Aislar la Ejecución de Migraciones
Si está desplegando su aplicación en varios servidores y ejecuta migraciones como parte del proceso de despliegue, probablemente no quiera que dos servidores intenten migrar la base de datos al mismo tiempo. Para evitar esto, puede usar la opción isolated al invocar el comando migrate.
Cuando se proporciona la opción isolated, Laravel adquirirá un bloqueo atómico usando el driver de caché de su aplicación antes de intentar ejecutar las migraciones. Todos los demás intentos de ejecutar el comando migrate mientras ese bloqueo esté activo no se ejecutarán; sin embargo, el comando aún saldrá con un código de estado exitoso:
php artisan migrate --isolated
Para utilizar esta función, su aplicación debe usar el driver de caché memcached, redis, dynamodb, database, file o array como driver de caché predeterminado. Además, todos los servidores deben comunicarse con el mismo servidor central de caché.
#Forzar la Ejecución de Migraciones en Producción
Algunas operaciones de migración son destructivas, lo que significa que pueden hacer que pierda datos. Para protegerlo de ejecutar estos comandos contra su base de datos de producción, se le pedirá confirmación antes de que se ejecuten los comandos. Para forzar la ejecución sin confirmación, use la opción --force:
php artisan migrate --force
#Revertir Migraciones
Para revertir la última operación de migración, puede usar el comando Artisan rollback. Este comando revierte el último "lote" de migraciones, que puede incluir varios archivos de migración:
php artisan migrate:rollback
Puede revertir un número limitado de migraciones proporcionando la opción step al comando rollback. Por ejemplo, el siguiente comando revertirá las últimas cinco migraciones:
php artisan migrate:rollback --step=5
Puede revertir un "lote" específico de migraciones proporcionando la opción batch al comando rollback, donde la opción batch corresponde a un valor de lote dentro de la tabla migrations de su aplicación. Por ejemplo, el siguiente comando revertirá todas las migraciones del lote tres:
php artisan migrate:rollback --batch=3
Si desea ver las sentencias SQL que se ejecutarán con las migraciones sin ejecutarlas realmente, puede usar la opción --pretend con el comando migrate:rollback:
php artisan migrate:rollback --pretend
El comando migrate:reset revertirá todas las migraciones de su aplicación:
php artisan migrate:reset
#Revertir y Migrar Usando un Solo Comando
El comando migrate:refresh revertirá todas sus migraciones y luego ejecutará el comando migrate. Este comando recrea efectivamente toda su base de datos:
php artisan migrate:refresh
# Refrescar la base de datos y ejecutar todos los seeders...
php artisan migrate:refresh --seed
Puede revertir y volver a migrar un número limitado de migraciones proporcionando la opción step al comando refresh. Por ejemplo, el siguiente comando revertirá y volverá a migrar las últimas cinco migraciones:
php artisan migrate:refresh --step=5
#Eliminar Todas las Tablas y Migrar
El comando migrate:fresh eliminará todas las tablas de la base de datos y luego ejecutará el comando migrate:
php artisan migrate:fresh
php artisan migrate:fresh --seed
Por defecto, el comando migrate:fresh solo elimina tablas de la conexión de base de datos predeterminada. Sin embargo, puede usar la opción --database para especificar la conexión de base de datos que debe migrarse. El nombre de la conexión de base de datos debe corresponder a una conexión definida en el database archivo de configuración de su aplicación:
php artisan migrate:fresh --database=admin
El comando migrate:fresh eliminará todas las tablas de la base de datos sin importar su prefijo. Este comando debe usarse con precaución cuando se desarrolla en una base de datos compartida con otras aplicaciones.
#Tablas
#Creación de Tablas
Para crear una nueva tabla en la base de datos, use el método create del facade Schema. El método create acepta dos argumentos: el primero es el nombre de la tabla, y el segundo es una función anónima que recibe un objeto Blueprint que puede usar para definir la nueva tabla:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->timestamps();
});
Al crear la tabla, puede usar cualquiera de los métodos de columna del constructor de esquemas para definir las columnas de la tabla.
#Determinar la Existencia de Tablas / Columnas
Puede determinar la existencia de una tabla o columna usando los métodos hasTable y hasColumn:
if (Schema::hasTable('users')) {
// La tabla "users" existe...
}
if (Schema::hasColumn('users', 'email')) {
// La tabla "users" existe y tiene una columna "email"...
}
#Conexión de Base de Datos y Opciones de Tabla
Si desea realizar una operación de esquema en una conexión de base de datos que no sea la conexión predeterminada de su aplicación, use el método connection:
Schema::connection('sqlite')->create('users', function (Blueprint $table) {
$table->id();
});
Además, algunas otras propiedades y métodos pueden usarse para definir otros aspectos de la creación de la tabla. La propiedad engine puede usarse para especificar el motor de almacenamiento de la tabla cuando se usa MySQL:
Schema::create('users', function (Blueprint $table) {
$table->engine = 'InnoDB';
// ...
});
Las propiedades charset y collation pueden usarse para especificar el conjunto de caracteres y la colación para la tabla creada cuando se usa MySQL:
Schema::create('users', function (Blueprint $table) {
$table->charset = 'utf8mb4';
$table->collation = 'utf8mb4_unicode_ci';
// ...
});
El método temporary puede usarse para indicar que la tabla debe ser "temporal". Las tablas temporales solo son visibles para la sesión de base de datos de la conexión actual y se eliminan automáticamente cuando se cierra la conexión:
Schema::create('calculations', function (Blueprint $table) {
$table->temporary();
// ...
});
Si desea agregar un "comentario" a una tabla de base de datos, puede invocar el método comment en la instancia de la tabla. Los comentarios de tabla actualmente solo son compatibles con MySQL y Postgres:
Schema::create('calculations', function (Blueprint $table) {
$table->comment('Business calculations');
// ...
});
#Actualización de Tablas
El método table del facade Schema puede usarse para actualizar tablas existentes. Al igual que el método create, el método table acepta dos argumentos: el nombre de la tabla y una función anónima que recibe una instancia de Blueprint que puede usar para agregar columnas o índices a la tabla:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->integer('votes');
});
#Renombrar / Eliminar Tablas
Para renombrar una tabla existente, use el método rename:
use Illuminate\Support\Facades\Schema;
Schema::rename($from, $to);
Para eliminar una tabla existente, puede usar los métodos drop o dropIfExists:
Schema::drop('users');
Schema::dropIfExists('users');
#Renombrar Tablas con Claves Foráneas
Antes de renombrar una tabla, debe verificar que cualquier restricción de clave foránea en la tabla tenga un nombre explícito en sus archivos de migración en lugar de dejar que Laravel asigne un nombre basado en convención. De lo contrario, el nombre de la restricción de clave foránea hará referencia al nombre antiguo de la tabla.
#Columnas
#Creación de Columnas
El método table del facade Schema puede usarse para actualizar tablas existentes. Al igual que el método create, el método table acepta dos argumentos: el nombre de la tabla y una función anónima que recibe una instancia de Illuminate\Database\Schema\Blueprint que puede usar para agregar columnas a la tabla:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->integer('votes');
});
#Tipos de Columnas Disponibles
El blueprint del constructor de esquemas ofrece una variedad de métodos que corresponden a los diferentes tipos de columnas que puede agregar a sus tablas de base de datos. Cada uno de los métodos disponibles se lista en la tabla a continuación:
<style> .collection-method-list > p { columns: 10.8em 3; -moz-columns: 10.8em 3; -webkit-columns: 10.8em 3; } .collection-method-list a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .collection-method code { font-size: 14px; } .collection-method:not(.first-collection-method) { margin-top: 50px; } </style>bigIncrements bigInteger binary boolean char dateTimeTz dateTime date decimal double enum float foreignId foreignIdFor foreignUlid foreignUuid geometryCollection geometry id increments integer ipAddress json jsonb lineString longText macAddress mediumIncrements mediumInteger mediumText morphs multiLineString multiPoint multiPolygon nullableMorphs nullableTimestamps nullableUlidMorphs nullableUuidMorphs point polygon rememberToken set smallIncrements smallInteger softDeletesTz softDeletes string text timeTz time timestampTz timestamp timestampsTz timestamps tinyIncrements tinyInteger tinyText unsignedBigInteger unsignedDecimal unsignedInteger unsignedMediumInteger unsignedSmallInteger unsignedTinyInteger ulidMorphs uuidMorphs ulid uuid year
#bigIncrements() {.collection-method .first-collection-method}
El método bigIncrements crea una columna equivalente a UNSIGNED BIGINT auto-incrementable (clave primaria):
$table->bigIncrements('id');
#bigInteger() {.collection-method}
El método bigInteger crea una columna equivalente a BIGINT:
$table->bigInteger('votes');
#binary() {.collection-method}
El método binary crea una columna equivalente a BLOB:
$table->binary('photo');
#boolean() {.collection-method}
El método boolean crea una columna equivalente a BOOLEAN:
$table->boolean('confirmed');
#char() {.collection-method}
El método char crea una columna equivalente a CHAR con una longitud dada:
$table->char('name', 100);
#dateTimeTz() {.collection-method}
El método dateTimeTz crea una columna equivalente a DATETIME (con zona horaria) con una precisión opcional (dígitos totales):
$table->dateTimeTz('created_at', $precision = 0);
#dateTime() {.collection-method}
El método dateTime crea una columna equivalente a DATETIME con una precisión opcional (dígitos totales):
$table->dateTime('created_at', $precision = 0);
#date() {.collection-method}
El método date crea una columna equivalente a DATE:
$table->date('created_at');
#decimal() {.collection-method}
El método decimal crea una columna equivalente a DECIMAL con la precisión dada (dígitos totales) y escala (dígitos decimales):
$table->decimal('amount', $precision = 8, $scale = 2);
#double() {.collection-method}
El método double crea una columna equivalente a DOUBLE con la precisión dada (dígitos totales) y escala (dígitos decimales):
$table->double('amount', 8, 2);
#enum() {.collection-method}
El método enum crea una columna equivalente a ENUM con los valores válidos dados:
$table->enum('difficulty', ['easy', 'hard']);
#float() {.collection-method}
El método float crea una columna equivalente a FLOAT con la precisión dada (dígitos totales) y escala (dígitos decimales):
$table->float('amount', 8, 2);
#foreignId() {.collection-method}
El método foreignId crea una columna equivalente a UNSIGNED BIGINT:
$table->foreignId('user_id');
#foreignIdFor() {.collection-method}
El método foreignIdFor agrega una columna equivalente a {column}_id para una clase de modelo dada. El tipo de columna será UNSIGNED BIGINT, CHAR(36) o CHAR(26) dependiendo del tipo de clave del modelo:
$table->foreignIdFor(User::class);
#foreignUlid() {.collection-method}
El método foreignUlid crea una columna equivalente a ULID:
$table->foreignUlid('user_id');
#foreignUuid() {.collection-method}
El método foreignUuid crea una columna equivalente a UUID:
$table->foreignUuid('user_id');
#geometryCollection() {.collection-method}
El método geometryCollection crea una columna equivalente a GEOMETRYCOLLECTION:
$table->geometryCollection('positions');
#geometry() {.collection-method}
El método geometry crea una columna equivalente a GEOMETRY:
$table->geometry('positions');
#id() {.collection-method}
El método id es un alias del método bigIncrements. Por defecto, el método creará una columna id; sin embargo, puede pasar un nombre de columna si desea asignar un nombre diferente a la columna:
$table->id();
#increments() {.collection-method}
El método increments crea una columna equivalente a UNSIGNED INTEGER auto-incrementable como clave primaria:
$table->increments('id');
#integer() {.collection-method}
El método integer crea una columna equivalente a INTEGER:
$table->integer('votes');
#ipAddress() {.collection-method}
El método ipAddress crea una columna equivalente a VARCHAR:
$table->ipAddress('visitor');
Cuando se usa Postgres, se creará una columna INET.
#json() {.collection-method}
El método json crea una columna equivalente a JSON:
$table->json('options');
#jsonb() {.collection-method}
El método jsonb crea una columna equivalente a JSONB:
$table->jsonb('options');
#lineString() {.collection-method}
El método lineString crea una columna equivalente a LINESTRING:
$table->lineString('positions');
#longText() {.collection-method}
El método longText crea una columna equivalente a LONGTEXT:
$table->longText('description');
#macAddress() {.collection-method}
El método macAddress crea una columna destinada a contener una dirección MAC. Algunos sistemas de base de datos, como PostgreSQL, tienen un tipo de columna dedicado para este tipo de datos. Otros sistemas de base de datos usarán una columna equivalente a cadena:
$table->macAddress('device');
#mediumIncrements() {.collection-method}
El método mediumIncrements crea una columna equivalente a UNSIGNED MEDIUMINT auto-incrementable como clave primaria:
$table->mediumIncrements('id');
#mediumInteger() {.collection-method}
El método mediumInteger crea una columna equivalente a MEDIUMINT:
$table->mediumInteger('votes');
#mediumText() {.collection-method}
El método mediumText crea una columna equivalente a MEDIUMTEXT:
$table->mediumText('description');
#morphs() {.collection-method}
El método morphs es un método de conveniencia que agrega una columna equivalente a {column}_id y una columna equivalente a {column}_type de tipo VARCHAR. El tipo de columna para {column}_id será UNSIGNED BIGINT, CHAR(36) o CHAR(26) dependiendo del tipo de clave del modelo.
Este método está destinado a usarse al definir las columnas necesarias para una relación polimórfica de Eloquent. En el siguiente ejemplo, se crearían las columnas taggable_id y taggable_type:
$table->morphs('taggable');
#multiLineString() {.collection-method}
El método multiLineString crea una columna equivalente a MULTILINESTRING:
$table->multiLineString('positions');
#multiPoint() {.collection-method}
El método multiPoint crea una columna equivalente a MULTIPOINT:
$table->multiPoint('positions');
#multiPolygon() {.collection-method}
El método multiPolygon crea una columna equivalente a MULTIPOLYGON:
$table->multiPolygon('positions');
#nullableTimestamps() {.collection-method}
El método nullableTimestamps es un alias del método timestamps:
$table->nullableTimestamps(0);
#nullableMorphs() {.collection-method}
El método es similar al método morphs; sin embargo, las columnas que se crean serán "nullable":
$table->nullableMorphs('taggable');
#nullableUlidMorphs() {.collection-method}
El método es similar al método ulidMorphs; sin embargo, las columnas que se crean serán "nullable":
$table->nullableUlidMorphs('taggable');
#nullableUuidMorphs() {.collection-method}
El método es similar al método uuidMorphs; sin embargo, las columnas que se crean serán "nullable":
$table->nullableUuidMorphs('taggable');
#point() {.collection-method}
El método point crea una columna equivalente a POINT:
$table->point('position');
#polygon() {.collection-method}
El método polygon crea una columna equivalente a POLYGON:
$table->polygon('position');
#rememberToken() {.collection-method}
El método rememberToken crea una columna equivalente a VARCHAR(100) que es nullable y está destinada a almacenar el token de autenticación actual para la función "remember me":
$table->rememberToken();
#set() {.collection-method}
El método set crea una columna equivalente a SET con la lista dada de valores válidos:
$table->set('flavors', ['strawberry', 'vanilla']);
#smallIncrements() {.collection-method}
El método smallIncrements crea una columna equivalente a UNSIGNED SMALLINT auto-incrementable como clave primaria:
$table->smallIncrements('id');
#smallInteger() {.collection-method}
El método smallInteger crea una columna equivalente a SMALLINT:
$table->smallInteger('votes');
#softDeletesTz() {.collection-method}
El método softDeletesTz añade una columna equivalente a TIMESTAMP nullable llamada deleted_at (con zona horaria) con una precisión opcional (dígitos totales). Esta columna está destinada a almacenar la marca de tiempo deleted_at necesaria para la funcionalidad de "soft delete" de Eloquent:
$table->softDeletesTz($column = 'deleted_at', $precision = 0);
#softDeletes() {.collection-method}
El método softDeletes añade una columna equivalente a TIMESTAMP nullable llamada deleted_at con una precisión opcional (dígitos totales). Esta columna está destinada a almacenar la marca de tiempo deleted_at necesaria para la funcionalidad de "soft delete" de Eloquent:
$table->softDeletes($column = 'deleted_at', $precision = 0);
#string() {.collection-method}
El método string crea una columna equivalente a VARCHAR con la longitud dada:
$table->string('name', 100);
#text() {.collection-method}
El método text crea una columna equivalente a TEXT:
$table->text('description');
#timeTz() {.collection-method}
El método timeTz crea una columna equivalente a TIME (con zona horaria) con una precisión opcional (dígitos totales):
$table->timeTz('sunrise', $precision = 0);
#time() {.collection-method}
El método time crea una columna equivalente a TIME con una precisión opcional (dígitos totales):
$table->time('sunrise', $precision = 0);
#timestampTz() {.collection-method}
El método timestampTz crea una columna equivalente a TIMESTAMP (con zona horaria) con una precisión opcional (dígitos totales):
$table->timestampTz('added_at', $precision = 0);
#timestamp() {.collection-method}
El método timestamp crea una columna equivalente a TIMESTAMP con una precisión opcional (dígitos totales):
$table->timestamp('added_at', $precision = 0);
#timestampsTz() {.collection-method}
El método timestampsTz crea columnas equivalentes a TIMESTAMP llamadas created_at y updated_at (con zona horaria) con una precisión opcional (dígitos totales):
$table->timestampsTz($precision = 0);
#timestamps() {.collection-method}
El método timestamps crea columnas equivalentes a TIMESTAMP llamadas created_at y updated_at con una precisión opcional (dígitos totales):
$table->timestamps($precision = 0);
#tinyIncrements() {.collection-method}
El método tinyIncrements crea una columna equivalente a UNSIGNED TINYINT auto-incrementable como clave primaria:
$table->tinyIncrements('id');
#tinyInteger() {.collection-method}
El método tinyInteger crea una columna equivalente a TINYINT:
$table->tinyInteger('votes');
#tinyText() {.collection-method}
El método tinyText crea una columna equivalente a TINYTEXT:
$table->tinyText('notes');
#unsignedBigInteger() {.collection-method}
El método unsignedBigInteger crea una columna equivalente a UNSIGNED BIGINT:
$table->unsignedBigInteger('votes');
#unsignedDecimal() {.collection-method}
El método unsignedDecimal crea una columna equivalente a UNSIGNED DECIMAL con una precisión opcional (dígitos totales) y escala (dígitos decimales):
$table->unsignedDecimal('amount', $precision = 8, $scale = 2);
#unsignedInteger() {.collection-method}
El método unsignedInteger crea una columna equivalente a UNSIGNED INTEGER:
$table->unsignedInteger('votes');
#unsignedMediumInteger() {.collection-method}
El método unsignedMediumInteger crea una columna equivalente a UNSIGNED MEDIUMINT:
$table->unsignedMediumInteger('votes');
#unsignedSmallInteger() {.collection-method}
El método unsignedSmallInteger crea una columna equivalente a UNSIGNED SMALLINT:
$table->unsignedSmallInteger('votes');
#unsignedTinyInteger() {.collection-method}
El método unsignedTinyInteger crea una columna equivalente a UNSIGNED TINYINT:
$table->unsignedTinyInteger('votes');
#ulidMorphs() {.collection-method}
El método ulidMorphs es un método de conveniencia que añade una columna equivalente a {column}_id de tipo CHAR(26) y una columna equivalente a {column}_type de tipo VARCHAR.
Este método está destinado a usarse al definir las columnas necesarias para una relación polimórfica Eloquent relationship que utiliza identificadores ULID. En el siguiente ejemplo, se crearían las columnas taggable_id y taggable_type:
$table->ulidMorphs('taggable');
#uuidMorphs() {.collection-method}
El método uuidMorphs es un método de conveniencia que añade una columna equivalente a {column}_id de tipo CHAR(36) y una columna equivalente a {column}_type de tipo VARCHAR.
Este método está destinado a usarse al definir las columnas necesarias para una relación polimórfica Eloquent relationship que utiliza identificadores UUID. En el siguiente ejemplo, se crearían las columnas taggable_id y taggable_type:
$table->uuidMorphs('taggable');
#ulid() {.collection-method}
El método ulid crea una columna equivalente a ULID:
$table->ulid('id');
#uuid() {.collection-method}
El método uuid crea una columna equivalente a UUID:
$table->uuid('id');
#year() {.collection-method}
El método year crea una columna equivalente a YEAR:
$table->year('birth_year');
#Modificadores de columnas
Además de los tipos de columnas listados arriba, existen varios "modificadores" de columnas que puede usar al agregar una columna a una tabla de base de datos. Por ejemplo, para hacer que una columna sea "nullable", puede usar el método nullable:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->string('email')->nullable();
});
La siguiente tabla contiene todos los modificadores de columnas disponibles. Esta lista no incluye los modificadores de índices:
| Modificador | Descripción |
|---|---|
->after('column') |
Coloca la columna "después" de otra columna (MySQL). |
->autoIncrement() |
Establece columnas INTEGER como auto-incrementables (clave primaria). |
->charset('utf8mb4') |
Especifica un conjunto de caracteres para la columna (MySQL). |
->collation('utf8mb4_unicode_ci') |
Especifica una colación para la columna (MySQL/PostgreSQL/SQL Server). |
->comment('my comment') |
Añade un comentario a una columna (MySQL/PostgreSQL). |
->default($value) |
Especifica un valor "por defecto" para la columna. |
->first() |
Coloca la columna "primera" en la tabla (MySQL). |
->from($integer) |
Establece el valor inicial de un campo auto-incrementable (MySQL / PostgreSQL). |
->invisible() |
Hace que la columna sea "invisible" para consultas SELECT * (MySQL). |
->nullable($value = true) |
Permite insertar valores NULL en la columna. |
->storedAs($expression) |
Crea una columna generada almacenada (MySQL / PostgreSQL). |
->unsigned() |
Establece columnas INTEGER como UNSIGNED (MySQL). |
->useCurrent() |
Establece columnas TIMESTAMP para usar CURRENT_TIMESTAMP como valor por defecto. |
->useCurrentOnUpdate() |
Establece columnas TIMESTAMP para usar CURRENT_TIMESTAMP al actualizar un registro (MySQL). |
->virtualAs($expression) |
Crea una columna generada virtual (MySQL / PostgreSQL / SQLite). |
->generatedAs($expression) |
Crea una columna identidad con opciones de secuencia especificadas (PostgreSQL). |
->always() |
Define la precedencia de valores de secuencia sobre la entrada para una columna identidad (PostgreSQL). |
->isGeometry() |
Establece el tipo de columna espacial a geometry - el tipo por defecto es geography (PostgreSQL). |
#Expresiones por defecto
El modificador default acepta un valor o una instancia de Illuminate\Database\Query\Expression. Usar una instancia de Expression evitará que Laravel envuelva el valor entre comillas y le permitirá usar funciones específicas de la base de datos. Una situación donde esto es particularmente útil es cuando necesita asignar valores por defecto a columnas JSON:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Ejecutar las migraciones.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->json('movies')->default(new Expression('(JSON_ARRAY())'));
$table->timestamps();
});
}
};
El soporte para expresiones por defecto depende del controlador de base de datos, la versión de la base de datos y el tipo de campo. Por favor, consulte la documentación de su base de datos.
#Orden de columnas
Al usar la base de datos MySQL, el método after puede usarse para agregar columnas después de una columna existente en el esquema:
$table->after('password', function (Blueprint $table) {
$table->string('address_line1');
$table->string('address_line2');
$table->string('city');
});
#Modificar columnas
El método change le permite modificar el tipo y los atributos de columnas existentes. Por ejemplo, puede querer aumentar el tamaño de una columna string. Para ver el método change en acción, aumentemos el tamaño de la columna name de 25 a 50. Para lograr esto, simplemente definimos el nuevo estado de la columna y luego llamamos al método change:
Schema::table('users', function (Blueprint $table) {
$table->string('name', 50)->change();
});
Al modificar una columna, debe incluir explícitamente todos los modificadores que desea conservar en la definición de la columna; cualquier atributo omitido será eliminado. Por ejemplo, para conservar los atributos unsigned, default y comment, debe llamar a cada modificador explícitamente al cambiar la columna:
Schema::table('users', function (Blueprint $table) {
$table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();
});
#Modificar columnas en SQLite
Si su aplicación utiliza una base de datos SQLite, debe instalar el paquete doctrine/dbal usando el gestor de paquetes Composer antes de modificar una columna. La biblioteca Doctrine DBAL se usa para determinar el estado actual de la columna y para crear las consultas SQL necesarias para realizar los cambios solicitados en su columna:
composer require doctrine/dbal
Si planea modificar columnas creadas usando el método timestamp, también debe agregar la siguiente configuración en el archivo de configuración config/database.php de su aplicación:
use Illuminate\Database\DBAL\TimestampType;
'dbal' => [
'types' => [
'timestamp' => TimestampType::class,
],
],
Al usar el paquete doctrine/dbal, los siguientes tipos de columnas pueden modificarse: bigInteger, binary, boolean, char, date, dateTime, dateTimeTz, decimal, double, integer, json, longText, mediumText, smallInteger, string, text, time, tinyText, unsignedBigInteger, unsignedInteger, unsignedSmallInteger, ulid y uuid.
#Renombrar columnas
Para renombrar una columna, puede usar el método renameColumn proporcionado por el constructor de esquemas:
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('from', 'to');
});
#Renombrar columnas en bases de datos antiguas
Si está ejecutando una instalación de base de datos anterior a alguna de las siguientes versiones, debe asegurarse de haber instalado la biblioteca doctrine/dbal mediante Composer antes de renombrar una columna:
- MySQL <
8.0.3 - MariaDB <
10.5.2 - SQLite <
3.25.0
#Eliminar columnas
Para eliminar una columna, puede usar el método dropColumn en el constructor de esquemas:
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('votes');
});
Puede eliminar múltiples columnas de una tabla pasando un arreglo de nombres de columnas al método dropColumn:
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['votes', 'avatar', 'location']);
});
#Eliminar columnas en bases de datos antiguas
Si está usando una versión de SQLite anterior a 3.35.0, debe instalar el paquete doctrine/dbal mediante Composer antes de usar el método dropColumn. No se admite eliminar o modificar múltiples columnas en una sola migración usando este paquete.
#Alias de comandos disponibles
Laravel proporciona varios métodos convenientes relacionados con eliminar tipos comunes de columnas. Cada uno de estos métodos se describe en la tabla a continuación:
| Comando | Descripción |
|---|---|
$table->dropMorphs('morphable'); |
Elimina las columnas morphable_id y morphable_type. |
$table->dropRememberToken(); |
Elimina la columna remember_token. |
$table->dropSoftDeletes(); |
Elimina la columna deleted_at. |
$table->dropSoftDeletesTz(); |
Alias del método dropSoftDeletes(). |
$table->dropTimestamps(); |
Elimina las columnas created_at y updated_at. |
$table->dropTimestampsTz(); |
Alias del método dropTimestamps(). |
#Índices
#Crear índices
El constructor de esquemas de Laravel soporta varios tipos de índices. El siguiente ejemplo crea una nueva columna email y especifica que sus valores deben ser únicos. Para crear el índice, podemos encadenar el método unique a la definición de la columna:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique();
});
Alternativamente, puede crear el índice después de definir la columna. Para hacerlo, debe llamar al método unique en el blueprint del constructor de esquemas. Este método acepta el nombre de la columna que debe recibir un índice único:
$table->unique('email');
Incluso puede pasar un arreglo de columnas a un método de índice para crear un índice compuesto:
$table->index(['account_id', 'created_at']);
Al crear un índice, Laravel generará automáticamente un nombre basado en la tabla, los nombres de las columnas y el tipo de índice, pero puede pasar un segundo argumento al método para especificar el nombre del índice usted mismo:
$table->unique('email', 'unique_email');
#Tipos de índices disponibles
La clase blueprint del constructor de esquemas de Laravel proporciona métodos para crear cada tipo de índice soportado por Laravel. Cada método de índice acepta un segundo argumento opcional para especificar el nombre del índice. Si se omite, el nombre se derivará de los nombres de la tabla y columna(s) usados para el índice, así como del tipo de índice. Cada uno de los métodos de índice disponibles se describe en la tabla a continuación:
| Comando | Descripción |
|---|---|
$table->primary('id'); |
Añade una clave primaria. |
$table->primary(['id', 'parent_id']); |
Añade claves compuestas. |
$table->unique('email'); |
Añade un índice único. |
$table->index('state'); |
Añade un índice. |
$table->fullText('body'); |
Añade un índice de texto completo (MySQL/PostgreSQL). |
$table->fullText('body')->language('english'); |
Añade un índice de texto completo en el idioma especificado (PostgreSQL). |
$table->spatialIndex('location'); |
Añade un índice espacial (excepto SQLite). |
#Longitudes de índices y MySQL / MariaDB
Por defecto, Laravel usa el conjunto de caracteres utf8mb4. Si está usando una versión de MySQL anterior a la 5.7.7 o MariaDB anterior a la 10.2.2, puede necesitar configurar manualmente la longitud por defecto de las cadenas generadas por las migraciones para que MySQL pueda crear índices para ellas. Puede configurar la longitud por defecto de las cadenas llamando al método Schema::defaultStringLength dentro del método boot de su clase App\Providers\AppServiceProvider:
use Illuminate\Support\Facades\Schema;
/**
* Inicializar cualquier servicio de la aplicación.
*/
public function boot(): void
{
Schema::defaultStringLength(191);
}
Alternativamente, puede habilitar la opción innodb_large_prefix para su base de datos. Consulte la documentación de su base de datos para instrucciones sobre cómo habilitar esta opción correctamente.
#Renombrar índices
Para renombrar un índice, puede usar el método renameIndex proporcionado por el blueprint del constructor de esquemas. Este método acepta el nombre actual del índice como primer argumento y el nombre deseado como segundo argumento:
$table->renameIndex('from', 'to')
Si su aplicación utiliza una base de datos SQLite, debe instalar el paquete doctrine/dbal mediante Composer antes de usar el método renameIndex.
#Eliminar índices
Para eliminar un índice, debe especificar el nombre del índice. Por defecto, Laravel asigna automáticamente un nombre de índice basado en el nombre de la tabla, el nombre de la columna indexada y el tipo de índice. Aquí algunos ejemplos:
| Comando | Descripción |
|---|---|
$table->dropPrimary('users_id_primary'); |
Elimina una clave primaria de la tabla "users". |
$table->dropUnique('users_email_unique'); |
Elimina un índice único de la tabla "users". |
$table->dropIndex('geo_state_index'); |
Elimina un índice básico de la tabla "geo". |
$table->dropFullText('posts_body_fulltext'); |
Elimina un índice de texto completo de la tabla "posts". |
$table->dropSpatialIndex('geo_location_spatialindex'); |
Elimina un índice espacial de la tabla "geo" (excepto SQLite). |
Si pasa un arreglo de columnas a un método que elimina índices, el nombre convencional del índice se generará basado en el nombre de la tabla, las columnas y el tipo de índice:
Schema::table('geo', function (Blueprint $table) {
$table->dropIndex(['state']); // Elimina el índice 'geo_state_index'
});
#Restricciones de claves foráneas
Laravel también ofrece soporte para crear restricciones de claves foráneas, que se usan para forzar la integridad referencial a nivel de base de datos. Por ejemplo, definamos una columna user_id en la tabla posts que referencia la columna id en la tabla users:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
Dado que esta sintaxis es bastante verbosa, Laravel proporciona métodos adicionales y más concisos que usan convenciones para ofrecer una mejor experiencia al desarrollador. Al usar el método foreignId para crear su columna, el ejemplo anterior puede reescribirse así:
Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
});
El método foreignId crea una columna equivalente a UNSIGNED BIGINT, mientras que el método constrained usará convenciones para determinar la tabla y columna referenciadas. Si el nombre de su tabla no coincide con las convenciones de Laravel, puede proporcionarlo manualmente al método constrained. Además, puede especificar el nombre que debe asignarse al índice generado:
Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained(
table: 'users', indexName: 'posts_user_id'
);
});
También puede especificar la acción deseada para las propiedades "on delete" y "on update" de la restricción:
$table->foreignId('user_id')
->constrained()
->onUpdate('cascade')
->onDelete('cascade');
También se proporciona una sintaxis alternativa y expresiva para estas acciones:
| Método | Descripción |
|---|---|
$table->cascadeOnUpdate(); |
Las actualizaciones deben propagarse en cascada. |
$table->restrictOnUpdate(); |
Las actualizaciones deben estar restringidas. |
$table->noActionOnUpdate(); |
No se realiza ninguna acción en actualizaciones. |
$table->cascadeOnDelete(); |
Las eliminaciones deben propagarse en cascada. |
$table->restrictOnDelete(); |
Las eliminaciones deben estar restringidas. |
$table->nullOnDelete(); |
Las eliminaciones deben establecer el valor de la clave foránea en null. |
Cualquier modificador de columna adicional debe llamarse antes del método constrained:
$table->foreignId('user_id')
->nullable()
->constrained();
#Eliminar claves foráneas
Para eliminar una clave foránea, puede usar el método dropForeign, pasando el nombre de la restricción de clave foránea que desea eliminar como argumento. Las restricciones de claves foráneas usan la misma convención de nombres que los índices. En otras palabras, el nombre de la restricción de clave foránea se basa en el nombre de la tabla y las columnas en la restricción, seguido del sufijo "_foreign":
$table->dropForeign('posts_user_id_foreign');
Alternativamente, puede pasar un arreglo que contenga el nombre de la columna que tiene la clave foránea al método dropForeign. El arreglo se convertirá en un nombre de restricción de clave foránea usando las convenciones de nombres de Laravel:
$table->dropForeign(['user_id']);
#Activar o desactivar restricciones de claves foráneas
Puede habilitar o deshabilitar las restricciones de claves foráneas dentro de sus migraciones usando los siguientes métodos:
Schema::enableForeignKeyConstraints();
Schema::disableForeignKeyConstraints();
Schema::withoutForeignKeyConstraints(function () {
// Restricciones deshabilitadas dentro de este closure...
});
SQLite deshabilita las restricciones de claves foráneas por defecto. Al usar SQLite, asegúrese de habilitar el soporte para claves foráneas en la configuración de su base de datos antes de intentar crearlas en sus migraciones. Además, SQLite solo soporta claves foráneas al crear la tabla y no cuando las tablas son alteradas.
#Eventos
Para conveniencia, cada operación de migración disparará un evento. Todos los siguientes eventos extienden la clase base Illuminate\Database\Events\MigrationEvent:
| Clase | Descripción |
|---|
| Illuminate\Database\Events\MigrationsStarted | Un lote de migraciones está a punto de ejecutarse. |
| Illuminate\Database\Events\MigrationsEnded | Un lote de migraciones ha terminado de ejecutarse. |
| Illuminate\Database\Events\MigrationStarted | Una migración individual está a punto de ejecutarse. |
| Illuminate\Database\Events\MigrationEnded | Una migración individual ha terminado de ejecutarse. |
| Illuminate\Database\Events\SchemaDumped | Se ha completado un volcado del esquema de la base de datos. |
| Illuminate\Database\Events\SchemaLoaded | Se ha cargado un volcado existente del esquema de la base de datos. |