Sin embargo, estoy tratando de crear claves foráneas en Laravel cuando migro mi tabla usando artisan
aparece el siguiente error:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign
key (`user_id`) references `users` (`id`))
Mi código de migración es así:
archivo de migración de prioridades
public function up()
{
//
Schema::create('priorities', function($table) {
$table->increments('id', true);
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('priority_name');
$table->smallInteger('rank');
$table->text('class');
$table->timestamps('timecreated');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::drop('priorities');
}
archivo de migración de usuarios
public function up()
{
//
Schema::table('users', function($table)
{
$table->create();
$table->increments('id');
$table->string('email');
$table->string('first_name');
$table->string('password');
$table->string('email_code');
$table->string('time_created');
$table->string('ip');
$table->string('confirmed');
$table->string('user_role');
$table->string('salt');
$table->string('last_login');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schemea::drop('users');
}
Cualquier idea sobre lo que he hecho mal, quiero obtener esto ahora, ya que tengo muchas tablas que necesito crear, por ejemplo, usuarios, clientes, proyectos, tareas, estados, prioridades, tipos, equipos. Idealmente, quiero crear tablas que contengan estos datos con las claves externas, es decir, clients_project
eproject_tasks
etc.
Espero que alguien pueda ayudarme a comenzar.
Schema::table
método ¡ayudó! ¡Gracias!$table->unsignedBigInteger('user_id')
si su user.id esbigIncrements
Pregunta ya respondida, pero espero que esto pueda ayudar a alguien más.
Este error se produjo para mí porque creé la tabla de migración con la clave externa en primer lugar antes de que la clave existiera como clave principal en su tabla original. Las migraciones se ejecutan en el orden en que fueron creadas, como lo indica el nombre del archivo generado después de ejecutarse
migrate:make
. Por ej2014_05_10_165709_create_student_table.php
.La solución fue cambiar el nombre del archivo con la clave externa a un tiempo anterior al archivo con la clave primaria como se recomienda aquí: http://forumsarchive.laravel.io/viewtopic.php?id=10246
Creo que también tuve que agregar
$table->engine = 'InnoDB';
fuente
Laravel ^ 5.8
Ejemplo
Imaginemos que está creando una aplicación simple basada en roles y necesita hacer referencia a user_id en la tabla PIVOT "role_user" .
2019_05_05_112458_create_users_table.php
2019_05_05_120634_create_role_user_pivot_table.php
Como puede ver, la línea comentada arrojará una excepción de consulta, porque, como se menciona en las notas de actualización, las columnas de clave externa deben ser del mismo tipo , por lo tanto, debe cambiar la clave anterior (en este ejemplo es user_id ) a bigInteger en la tabla role_user o cambie el método bigIncrements a incrementos en la tabla de usuarios y use la línea comentada en la tabla dinámica, depende de usted.
Espero haber podido aclararles este problema.
fuente
Schema::table('goal_objective', function (Blueprint $table) { $table->bigInteger('job_title_id')->after('target')->unsigned()->nullable(); $table->foreign('job_title_id')->references('id')->on('job_titles')->onDelete('set null'); }
Funcionó. Gracias.En mi caso, el problema era que la tabla principal ya tenía registros y estaba obligando a la nueva columna a no ser NULL. Por lo tanto, agregar un -> nullable () a la nueva columna hizo el truco. En el ejemplo de la pregunta sería algo como esto:
$table->integer('user_id')->unsigned()->nullable();
o:
$table->unsignedInteger('user_id')->nullable();
Espero que esto ayude a alguien!
fuente
En mi caso, el problema era que la migración autogenerada para la
users
tabla estaba configurandoEntonces tuve que cambiar el tipo de columna
hacer que mi migración con la clave externa funcione.
Esto con laravel
5.8.2
fuente
En mi caso, el problema fue con el tiempo de migración, tenga cuidado al crear migraciones, primero cree la migración secundaria que la migración base. Porque si crea primero la migración base que tiene su clave externa, buscará una tabla secundaria y no habrá una tabla que luego arroje una excepción.
Además:
Cuando crea la migración, tiene una marca de tiempo al comienzo. supongamos que ha creado un gato de migración para que se vea
2015_08_19_075954_the_cats_time.php
y tenga este códigoY después de crear la tabla base, crea otra raza de migración , que es la tabla secundaria, tiene su propio sello de fecha y hora de creación. El código se verá así:
parece que ambas tablas son correctas, pero cuando ejecuta php artisan migrate . Lanzará una excepción porque la migración primero creará la tabla base en su base de datos porque usted ha creado esta migración primero y nuestra tabla base tiene una restricción de clave externa que buscará la tabla secundaria y la tabla secundaria no existe, lo que probablemente sea una excepción..
Entonces:
hecho funcionará
fuente
En mi caso, solo cambio el orden en que las migraciones se ejecutan manualmente para que los usuarios de la tabla se creen primero.
En la base de datos de carpetas / migraciones / su nombre de archivo de migración tiene este formato: year_month_day_hhmmss_create_XXXX_table.php
Simplemente cambie el nombre de crear archivo de usuario para que la fecha de creación de la tabla de prioridades de la tabla se establezca después de la fecha del usuario (incluso un segundo más tarde es suficiente)
fuente
En laravel 5.8, users_table usa
bigIncrements('id')
el tipo de datos para la clave primaria. De modo que cuando desee hacer referencia a una restricción de clave externa, suuser_id
columna debe ser deunsignedBigInteger('user_id')
tipo.fuente
Estaba teniendo el mismo problema al usar Laravel 5.8. Después de echar un vistazo más de cerca a laravel docs, además, aquí Migraciones y bigIncrements . La forma en que lo resolví es agregando claves primarias "$ table-> bigIncrements ('id')" a cada tabla que está relacionada con la tabla "usuarios" y sus asociaciones, en mi caso la tabla "rol" . Por último, tenía "$ table-> unsignedBigInteger" para asociar roles a los usuarios (muchos a muchos), es decir, la tabla "role_user" .
fuente
Tuve este problema con laravel 5.8 y arreglé este código, como se muestra aquí en la documentación de Laravel , donde estoy agregando una clave foránea.
entonces corrí
$ php artisan migrate:refresh
Dado que esta sintaxis es bastante detallada, Laravel proporciona métodos adicionales y terser que utilizan la convención para proporcionar una mejor experiencia de desarrollador. El ejemplo anterior podría escribirse así:
fuente
Usar Laravel 5.3 tuvo el mismo problema.
La solución fue usar unsignedInteger en lugar de entero ('nombre') -> unsigned () .
Entonces esto es lo que funcionó
La razón por la que esto funcionó es el hecho de que al usar entero ('nombre') -> sin firmar la columna creada en la tabla tenía una longitud de 11, pero cuando se usaba unsigedInteger ('nombre') la columna tenía una longitud de 10.
La longitud 10 es la longitud de las claves primarias cuando se usa Laravel, por lo que la longitud de las columnas coincide.
fuente
Este error ocurrió porque, mientras que la tabla que intentaba crear era InnoDB, ¡la tabla externa con la que intentaba relacionarla era una tabla MyISAM!
fuente
No podemos agregar relaciones, a menos que se creen tablas relacionadas. Laravel ejecuta las migraciones ordenadas por fecha de archivos de migración. Entonces, si desea crear una relación con una tabla que existe en el segundo archivo de migración, falla.
Enfrenté el mismo problema, así que creé un archivo de migración más por fin para especificar todas las relaciones.
fuente
Tenga en cuenta: cuando Laravel configura una tabla usando
que es estándar en la mayoría de las migraciones, esto configurará un campo entero sin signo. Por lo tanto, al hacer una referencia externa de otra tabla a este campo, asegúrese de que en la tabla de referencia, establezca el campo en UnsignedInteger y no (lo que supuse que era) campo UnsignedBigInteger.
Por ejemplo: en el archivo de migración 2018_12_12_123456_create_users_table.php:
Luego, en el archivo de migración 2018_12_12_18000000_create_permissions_table.php, que configura la referencia externa a los usuarios:
fuente
Deberías escribir de esta manera
El campo de clave externa no debe estar firmado , ¡espero que ayude!
fuente
Para agregar la restricción de clave externa en laravel, lo siguiente funcionó para mí:
Cree la columna para que sea clave externa de la siguiente manera:
Agregar la línea de restricción inmediatamente después de (1) es decir
fuente
Sé que es una pregunta antigua, pero asegúrese de que si está trabajando con referencias, se defina el motor de soporte adecuado. configura el motor innodb para ambas tablas y el mismo tipo de datos para las columnas de referencia
fuente
Entrando aquí unos años después de la pregunta original, usando laravel 5.1, tuve el mismo error ya que mis migraciones fueron generadas por computadora con el mismo código de fecha. Revisé todas las soluciones propuestas, luego refactoré para encontrar la fuente del error.
En las siguientes transmisiones, y al leer estas publicaciones, creo que la respuesta correcta es similar a la respuesta de Vickies, con la excepción de que no es necesario agregar una llamada de esquema por separado. No necesita poner la mesa en Innodb, supongo que ahora Laravel lo está haciendo.
Las migraciones simplemente deben programarse correctamente, lo que significa que modificará el código de fecha (más adelante) en el nombre del archivo para las tablas en las que necesita claves foráneas. Alternativamente o además, baje el código de fecha para las tablas que no necesitan claves foráneas.
La ventaja de modificar el código de fecha es que su código de migración será más fácil de leer y mantener.
Hasta ahora, mi código funciona ajustando el código de tiempo para retrasar las migraciones que necesitan claves externas.
Sin embargo, tengo cientos de tablas, así que al final tengo una última tabla solo para claves foráneas. Solo para que las cosas fluyan. Supongo que los pondré en el archivo correcto y modificaré el código de fecha mientras los pruebo.
Entonces, un ejemplo: archivo 2016_01_18_999999_create_product_options_table. Este necesita que se cree la tabla de productos. Mira los nombres de los archivos.
la tabla de productos: esto debe migrar primero. 2015_01_18_000000_create_products_table
Y finalmente, al final, el archivo que estoy usando temporalmente para resolver problemas, que refactorizaré a medida que escriba pruebas para los modelos que denominé 9999_99_99_999999_create_foreign_keys.php. Estas claves se comentan cuando las saqué, pero entiendes el punto.
fuente
Tan sencillo !!!
si crea su primer
'priorities'
archivo de migración, Laravel se ejecuta por primera vez'priorities'
mientras la'users'
tabla no existe.¡Cómo puede agregar una relación a una tabla que no existe !.
Solución: extraiga los códigos de clave externa de la
'priorities'
tabla. su archivo de migración debería ser así:y agregue a un nuevo archivo de migración, aquí está su nombre
create_prioritiesForeignKey_table
y agregue estos códigos:fuente
asegúrese de que su columna externa esté muy extendida de la columna clave principal
Me refiero a que su clave anterior (en la segunda tabla) debe ser del mismo tipo que su clave principal ponter (en la primera tabla)
la clave principal de su puntero debe agregar un método sin signo, déjeme mostrarle:
en su PRIMERA tabla de migración:
en su SEGUNDA tabla de migración:
OTRO EJEMPLO PARA VER LA DIFERENCIA
en su PRIMERA tabla de migración:
en su SEGUNDA tabla de migración:
VER TABLAS DE TABLAS DE TIPOS NUMÉRICOS MYSQL
fuente
Una cosa que he notado es que si las tablas usan un motor diferente que la restricción de clave externa no funciona.
Por ejemplo, si una tabla usa:
Y los otros usos
generaría un error:
Puede solucionar esto simplemente agregando InnoDB al final de la creación de su tabla de la siguiente manera:
fuente
En mi caso, hacía referencia a una columna entera
id
en una columna de cadenauser_id
. Cambié:$table->string('user_id')
a:
$table->integer('user_id')->unsigned();
Espero que ayude a alguien!
fuente
La esencia es que el método externo se utiliza
ALTER_TABLE
para convertir un campo preexistente en una clave externa. Por lo tanto, debe definir el tipo de tabla antes de aplicar la clave externa. Sin embargo, no tiene que estar en unaSchema::
llamada separada . Puedes hacer ambas cosas dentro de crear, así:También tenga en cuenta que el tipo de
user_id
se establece en unsigned para que coincida con la clave externa.fuente
Puede pasar directamente el parámetro booleano en la columna entera diciendo que debe estar sin signo o no. En laravel 5.4 el siguiente código resolvió mi problema.
Aquí, el segundo parámetro falso representa que no debe incrementarse automáticamente y el tercer parámetro verdadero representa que no debe estar firmado. Puede mantener la restricción de clave externa en la misma migración o separarla. Funciona en ambos.
fuente
Si ninguna de las soluciones anteriores funciona para los novatos, verifique si ambas ID tienen el mismo tipo: ambas son
integer
o ambas sonbigInteger
, ... Puede tener algo como esto:Tabla principal (usuarios por ejemplo)
Tabla secundaria (prioridades, por ejemplo)
Esta consulta fallará porque
users.id
es unBIG INTEGER
mientras quepriorities.user_id
es unINTEGER
.La consulta correcta en este caso sería la siguiente:
fuente
En mi caso no funcionó hasta que ejecuté el comando
de esa manera puede dejar las claves foráneas dentro del esquema de creación
fuente
También puede ser su orden de migración de creación. Si primero crea una tabla de prioridades, y después de la tabla de usuarios, entonces será incorrecto. Debido a la primera migración buscando la tabla de usuarios. Por lo tanto, debe cambiar el orden de la migración en
directorio
fuente
Para mí, la columna de la tabla a la que hacía referencia mi tabla secundaria no estaba indexada.
Ignora el terrible nombre, es de otro sistema terriblemente diseñado.
fuente
Algunas veces este error puede deberse a una secuencia de migraciones.
Usuarios similares y Orden son dos tablas
La tabla de pedidos tiene una clave extranjera de usuarios (durante la migración, si la tabla de pedidos migra primero, causará el problema porque no hay usuarios que coincidan con la clave externa)
Solución: solo coloque la tabla de actualización de pedidos debajo de los usuarios para actualizar
Ejemplo: en mi caso Tablas de educación y universidad Tabla de educación
En la Universidad
fuente
Una cosa que creo que falta en las respuestas aquí, y corríjame si estoy equivocado, pero las claves foráneas deben indexarse en la tabla dinámica. Al menos en mysql ese parece ser el caso.
fuente