una tipos tablas primaria modelo migrar migracion llaves foraneas especifica ejecutar datos crear con clave laravel laravel-4 foreign-keys migration eloquent

tipos - migrar laravel



Migración: no se puede agregar restricción de clave externa en laravel (23)

Estoy tratando de crear claves externas en Laravel, sin embargo, cuando migro mi tabla utilizando artisan me arrojan 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 mismo, 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, i..e clients_project y project_tasks etc.

Espero que alguien pueda ayudarme a comenzar.

Gracias por adelantado.


Añádalo en dos pasos, y también es bueno hacerlo sin firmar:

public function up() { Schema::create(''priorities'', function($table) { $table->increments(''id'', true); $table->integer(''user_id'')->unsigned(); $table->string(''priority_name''); $table->smallInteger(''rank''); $table->text(''class''); $table->timestamps(''timecreated''); }); Schema::table(''priorities'', function($table) { $table->foreign(''user_id'')->references(''id'')->on(''users''); }); }


Agregando a la solución unsigned () , al crear una base de datos usando InnoDB como el motor de las tablas. Asegúrese de que la tabla foránea se haya creado antes que las tablas que dependerán de la tabla externa .

Ilustración

Caso 1 (tablas nuevas)

Supongamos que su tabla de comentarios depende de la tabla de publicaciones (tabla externa). Necesita crear la tabla de publicaciones antes de crear la tabla de comentarios

Caso 2 (tablas ya existentes)

Supongamos que su tabla de comentarios fue creada antes de su tabla de publicaciones . Cree su tabla de publicaciones en un nuevo archivo de migración y luego agregue las claves externas de la tabla de comentarios en un nuevo archivo de migración que cree después de que se haya creado la migración de la tabla postal .

PD

Supongo que estás usando laravel


Creo: la clave de referencia debe ser "índice". por ejemplo: (abajo)

public function up() { Schema::create(''clicks'', function (Blueprint $table) { $table->increments(''id''); $table->string(''viewer_id''); $table->integer(''link_id'')->index()->unsigned(); $table->string(''time''); $table->timestamps(); }); Schema::table(''clicks'', function($table) { $table->foreign(''link_id'')->references(''id'')->on(''links'')->onDelete(''cascade''); }); }

buena suerte.


El uso de Laravel 5.3 tuvo el mismo problema.

La solución fue usar unsignedInteger en lugar de enterger (''name'') -> unsigned () .

Así que esto es lo que funcionó

$table->unsignedInt(''column_name''); $table->foreign(''column_name'')->references(''id'')->on(''table_name'');

La razón por la que esto funcionó es el hecho de que cuando se usa entero (''nombre'') -> sin signo, la columna creada en la tabla tenía longitud 11, pero cuando se usa unsigedInteger (''nombre'') la columna tenía longitud 10.

La longitud 10 es la longitud de las teclas principales cuando se usa Laravel para que la longitud de las columnas coincida.


En mi caso, el problema era que el tiempo de migración era cuidado al crear migraciones, en primer lugar, creaba la migración secundaria que la migración base. Porque si primero crea una migración base que tenga su clave externa buscará una tabla secundaria y no habrá una tabla que arrojar una excepción.

Además:

Cuando crea una migración, tiene una marca de tiempo al comienzo. digamos que creaste un gato de migración para que se vea como 2015_08_19_075954_the_cats_time.php y tiene este código

<?php use Illuminate/Database/Schema/Blueprint; use Illuminate/Database/Migrations/Migration; class TheCatsTime extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create(''cat'', function (Blueprint $table) { $table->increments(''id''); $table->string(''name''); $table->date(''date_of_birth''); $table->integer(''breed_id'')->unsigned()->nullable(); }); Schema::table(''cat'', function($table) { $table->foreign(''breed_id'')->references(''id'')->on(''breed''); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop(''cat''); } }

Y después de crear la tabla base, crea otra raza de migración que es una tabla hija, tiene su propia marca de fecha y hora de creación. El código se verá así:

<?php use Illuminate/Database/Schema/Blueprint; use Illuminate/Database/Migrations/Migration; class BreedTime extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create(''breed'', function (Blueprint $table) { $table->increments(''id''); $table->string(''name''); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop(''breed''); } }

parece que ambas tablas son correctas, pero cuando ejecutas php artesanal migra . Lanzará una excepción porque la migración primero creará la tabla base en su base de datos porque primero ha creado esta migración y nuestra tabla base tiene una restricción de clave externa que buscará una tabla secundaria y la tabla secundaria no existe, que probablemente sea una excepción..

Asi que:

Primero crea una migración de tabla hija.

Cree la migración de la tabla base después de crear la migración secundaria.

php artesano migrar.

hecho funcionará


En mi caso, el problema era que la tabla principal ya tenía registros y estaba forzando a la nueva columna a no ser NULL. Entonces, 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!


En mi caso, estaba haciendo referencia a una columna de id enteros en una columna user_id cadena . Cambié:

$table->string(''user_id'')

a:

$table->integer(''user_id'')->unsigned();

Espero que ayude a alguien!


En mi caso, olvidé usar paréntesis para ->unsigned() cuando definí la columna.

Código Worng: $table->integer(''permission_id'')->unsigned;

Código verdadero: $table->integer(''permission_id'')->unsigned();


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 carpeta database / migrations / your migration nombre de archivo 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 más tarde que la fecha de usuario (incluso un segundo más tarde es suficiente)


Entrando aquí unos pocos 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 de error.

En los siguientes laracasts, y al leer estas publicaciones, creo que la respuesta correcta es similar a la respuesta de Vickies, con la excepción de que no necesita agregar una llamada de esquema separada. No necesita configurar la tabla para Innodb, supongo que ahora Laravel está haciendo eso.

Las migraciones simplemente deben sincronizarse correctamente, lo que significa que modificará el código de fecha hacia arriba (más adelante) en el nombre del archivo para las tablas en las que necesite claves externas. Alternativamente o además, baje el código de fecha para las tablas que no necesitan claves externas.

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 externas. Solo para que las cosas fluyan. Supongo que los incluiré en el archivo correcto y modificaré el código de fecha cuando los pruebe.

Así que un ejemplo: archivo 2016_01_18_999999_create_product_options_table. Este necesita la tabla de productos que se creará. Mira los nombres de los archivos.

public function up() { Schema::create(''product_options'', function (Blueprint $table) { $table->increments(''id''); $table->integer(''product_attribute_id'')->unsigned()->index(); $table->integer(''product_id'')->unsigned()->index(); $table->string(''value'', 40)->default(''''); $table->timestamps(); //$table->foreign(''product_id'')->references(''id'')->on(''products''); $table->foreign(''product_attribute_id'')->references(''id'')->on(''product_attributes''); $table->foreign(''product_id'')->references(''id'')->on(''products''); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop(''product_options''); }

la tabla de productos: esto necesita migrar primero. 2015_01_18_000000_create_products_table

public function up() { Schema::create(''products'', function (Blueprint $table) { $table->increments(''id''); $table->string(''style_number'', 64)->default(''''); $table->string(''title'')->default(''''); $table->text(''overview'')->nullable(); $table->text(''description'')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop(''products''); }

Y finalmente, al final, el archivo que estoy usando temporalmente para resolver problemas, que voy a refactorizar a medida que escribo 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.

public function up() { // Schema::table(''product_skus'', function ($table) { // $table->foreign(''product_id'')->references(''id'')->on(''products'')->onDelete(''cascade''); // }); } /** * Reverse the migrations. * * @return void */ public function down() { // Schema::table(''product_skus'', function ($table) // { // $table->dropForeign(''product_skus_product_id_foreign''); // });


Este error ocurrió para mí porque, mientras que la tabla que estaba tratando de crear era InnoDB, ¡la tabla externa con la que estaba tratando de relacionarla era una tabla MyISAM!


La pregunta ya fue respondida, pero espero que esto pueda ayudar a otra persona.

Se produjo este error 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 se crearon, tal como lo indica el nombre de archivo generado después de ejecutar migrate:make . Ej. 2014_05_10_165709_create_student_table.php .

La solución fue cambiar el nombre del archivo con la clave externa a una hora anterior al archivo con la clave principal, tal como se recomienda aquí: http://forumsarchive.laravel.io/viewtopic.php?id=10246

Creo que también tuve que agregar $table->engine = ''InnoDB'';


Lo esencial es que el método foráneo usa ALTER_TABLE para convertir un campo preexistente en una clave foránea. Entonces debe definir el tipo de tabla antes de aplicar la clave externa. Sin embargo, no tiene que estar en una llamada Schema:: separada. Puedes hacer ambas cosas dentro de create, así:

public function up() { Schema::create(''priorities'', function($table) { $table->increments(''id'', true); $table->integer(''user_id'')->unsigned(); $table->foreign(''user_id'')->references(''id'')->on(''users''); $table->string(''priority_name''); $table->smallInteger(''rank''); $table->text(''class''); $table->timestamps(''timecreated''); }); }

También tenga en cuenta que el tipo de user_id se establece en unsigned para que coincida con la clave externa.


Me volví loco, solo tuve un error tipográfico:

unsinged() insteads de unsigned() .


No podemos agregar relaciones, a menos que se creen tablas relacionadas. Las migraciones de ejecución de Lareavel ordenan por fecha de archivos de migración. Entonces, si desea crear una relación con una tabla que exista en el segundo archivo de migración, falla.

Enfrenté el mismo problema, así que creé un archivo de migración más para especificar todas las relaciones.

Schema::table(''properties'', function(Blueprint $table) { $table->foreign(''user'')->references(''id'')->on(''users'')->onDelete(''cascade''); $table->foreign(''area'')->references(''id'')->on(''areas'')->onDelete(''cascade''); $table->foreign(''city'')->references(''id'')->on(''cities'')->onDelete(''cascade''); $table->foreign(''type'')->references(''id'')->on(''property_types'')->onDelete(''cascade''); }); Schema::table(''areas'', function(Blueprint $table) { $table->foreign(''city_id'')->references(''id'')->on(''cities'')->onDelete(''cascade''); });


Para agregar la restricción de clave externa en laravel, lo siguiente funcionó para mí:

  1. Cree la columna para ser clave externa de la siguiente manera:

    $table->integer(''column_name'')->unsigned();

  2. Agregar la línea de restricción inmediatamente después de (1) es decir

    $table->integer(''column_name'')->unsigned(); $table->foreign(''column_name'')->references(''pk_of_other_table'')->on(''other_table'');


Puede pasar directamente el parámetro booleano en la columna de enteros diciendo que debe estar sin firmar o no. En laravel 5.4 siguiente código resolvió mi problema.

$table->integer(''user_id'', false, true);

Aquí el segundo parámetro falso representa que no debe autoincrementarse y el tercer parámetro verdadero representa que debe estar sin signo. Puede mantener la restricción de clave externa en la misma migración o separarla. Funciona en ambos.


Sé que es una vieja pregunta, pero asegúrese de que si está trabajando con referencias, se define el motor de soporte adecuado. establecer innodb engine para ambas tablas y el mismo tipo de datos para las columnas de referencia

$table->engine = ''InnoDB'';


Si ninguna de las soluciones anteriores funciona para los novatos, compruebe si ambas identificaciones tienen el mismo tipo: ambos son integer o ambos son bigInteger . Más bigInteger , ... Puede tener algo como esto:

Tabla principal (usuarios, por ejemplo)

$table->bigIncrements(''id'');

Tabla de niños (prioridades, por ejemplo)

$table->unsignedInteger(''user_id''); $table->foreign(''user_id'')->references(''id'')->on(''users'')->onDelete(''cascade'');

Esta consulta users.id porque users.id es un BIG INTEGER mientras que priorities.user_id es un INTEGER .

La consulta correcta en este caso sería la siguiente:

$table->unsignedBigInteger(''user_id''); $table->foreign(''user_id'')->references(''id'')->on(''users'')->onDelete(''cascade'');


Tan sencillo !!!

si primero crea ''priorities'' archivo de migración de ''priorities'' , Laravel primero ejecuta ''priorities'' mientras ''users'' tabla de ''users'' no existe.

cómo puede agregar relación a una tabla que no existe !.

Solución: extraiga los códigos de clave externa de ''priorities'' tabla de ''priorities'' . su archivo de migración debería ser así:

y agregue a un nuevo archivo de migración, aquí su nombre es create_prioritiesForeignKey_table y agregue estos códigos:

public function up() { Schema::table(''priorities'', function (Blueprint $table) { $table->foreign(''user_id'') ->references(''id'') ->on(''users''); }); }


Tuve el mismo error con Laravel 5 al hacer una tabla dinámica, y el problema en mi caso era que no tenía

->onDelete(''cascade'');


Una cosa que creo que falta en las respuestas aquí, y por favor corrígeme si me equivoco, pero las claves foráneas deben estar indexadas en la tabla pivote. Al menos en mysql ese parece ser el caso.

public function up() { Schema::create(''image_post'', function (Blueprint $table) { $table->engine = ''InnoDB''; $table->increments(''id''); $table->integer(''image_id'')->unsigned()->index(); $table->integer(''post_id'')->unsigned()->index(); $table->timestamps(); }); Schema::table(''image_post'', function($table) { $table->foreign(''image_id'')->references(''id'')->on(''image'')->onDelete(''cascade''); $table->foreign(''post_id'')->references(''id'')->on(''post'')->onDelete(''cascade''); }); }


asegúrate de que tu columna externa esté sobre la rabia amplia de la columna de clave externa

I significa que tu foreingkey (en la segunda tabla) debe ser del mismo tipo que tu ponter pricipal key (en la primera tabla)

la clave principal del puntero debe ser un método sin signo, déjame mostrar:

en su PRIMERA tabla de migración:

$table->increments(''column_name''); //is INTEGER and UNSIGNED

en su SEGUNDA tabla de migración:

$table->integer(''column_forein_name'')->unsigned(); //this must be INTEGER and UNSIGNED $table->foreign(''column_forein_name'')->references(''column_name'')->on(''first_table_name'');

OTRO EJEMPLO PARA VER LA DIFERENCIA

en su PRIMERA tabla de migración:

$table->mediumIncrements(''column_name''); //is MEDIUM-INTEGER and UNSIGNED

en su SEGUNDA tabla de migración:

$table->mediumInteger(''column_forein_name'')->unsigned(); //this must be MEDIUM-INTEGER and UNSIGNED $table->foreign(''column_forein_name'')->references(''column_name'')->on(''first_table_name'');

VER RANGOS DE MESA DE TIPOS NUMÉRICOS DE MYSQL