I'm new on Laravel framework, I try too create table with 2 foreign key and I want they become primary in this table. But I have an error when I write php artisan migrate
SQLSTATE[42000]: Syntax error or access violation: 1068 Multiple primary ke
y defined (SQL: alter table doc_tag add primary key doc_tag_id_tag_primar
y(id_tag)
Schema::create('doc_tag', function(Blueprint $table)
{
$table->integer('id_doc')->unsigned();
$table->primary('id_doc');
$table->foreign('id_doc')
->references('id')
->on('doc');
$table->integer('id_tag')->unsigned();
$table->primary('id_tag');
$table->foreign('id_tag')
->references('id')
->on('tag');
});
I know the SQL code which is : (But I do not really know how to translate this SQL code in Laravel)
CREATE TABLE IF NOT EXISTS `Doc_project`.`document_has_Tags` (
`document_id_document` INT NOT NULL,
`Tags_id_Tag` INT NOT NULL,
PRIMARY KEY (`document_id_document`, `Tags_id_Tag`),
INDEX `fk_document_has_Tags_Tags1_idx` (`Tags_id_Tag` ASC),
INDEX `fk_document_has_Tags_document1_idx` (`document_id_document` ASC),
CONSTRAINT `fk_document_has_Tags_document1`
FOREIGN KEY (`document_id_document`)
REFERENCES `Doc_project`.`document` (`id_document`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_document_has_Tags_Tags1`
FOREIGN KEY (`Tags_id_Tag`)
REFERENCES `Doc_project`.`Tags` (`id_Tag`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
It's an N:N relation
Someone have an idea ?
Eloquent doesn't support multiple primary keys, but if you still want it, send an array to your primary(...).
So in your case:
Schema::create('doc_tag', function(Blueprint $table)
{
$table->integer('id_doc')->unsigned();
$table->integer('id_tag')->unsigned();
$table->primary(['id_tag', 'id_doc']);
$table->foreign('id_doc')
->references('id')
->on('doc');
$table->foreign('id_tag')
->references('id')
->on('tag');
});
If you want to create primary key on 2 or more columns you should use:
$table->primary(['id_doc','id_tag']);
Related
Trying to assign foreign key but when you run migrate, I get this this error, I do not understand what the problem is.
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table categories add constraint categories_parent_key_foreign foreign key (parent_key) references categories (key) on delete cascade)
$table->bigIncrements('id');
$table->string('key', 64)->unique();
$table->string('parent_key', 64)->nullable()->index();
$table->string('title', 256)->index()->unique();
$table->foreign('parent_key')->references('key')
->on((new Category())->getConnection()->getDatabaseName() . '.' . Category::TABLE)
->onDelete('cascade');
I had the same problem.
The problem arises when a model has a relationship with itself (self-relation).
To solve this problem, first, the migration file must be created and then the foreign key must be assigned in another migration file.
You must remove the foreign key assignment from the migration file and create the new migration file after that, then add relations statements to assign a foreign key. (the order of the migration files is important).
create_category_table
public function up(): void
{
$table->bigIncrements('id');
$table->string('key', 64)->unique();
$table->string('parent_key', 64)->nullable()->index();
$table->string('title', 256)->index()->unique();
}
create_category_relation_table
public function up(): void
{
$table->foreign('parent_key')->references('key')
->on((new Category())->getConnection()->getDatabaseName() . '.' . Category::TABLE)
->onDelete('cascade');
}
And then php artisan migration
In my case the problem was in the different datatypes of the referenced table key and the key reference. For instance, integer(unsigned) vs bigInteger(unsigned).
I'm trying to figure out how migrations in Laravel work. Here you can see I'm creating 2 tables. And in the second table (RealNationalLeague), I'm having foreign keys to two columns (real_nation_id, level) in the first table (RealNationalLeagueLevel).
public function up()
{
...
Schema::create(Model\RealNationalLeagueLevel::TABLE, function (Blueprint $table) {
$table->unsignedInteger("real_nation_id");
$table->unsignedTinyInteger("level");
$table->foreign("real_nation_id")->references("id")->on(Model\RealNation::TABLE);
$table->primary(["real_nation_id", "level"]);
});
Schema::create(Model\RealNationalLeague::TABLE, function (Blueprint $table) {
$table->increments("id");
$table->unsignedInteger("real_nation_id");
$table->unsignedTinyInteger("level");
$table->string("name", 32);
$table->foreign("real_nation_id")->references("real_nation_id")->on(Model\RealNationalLeagueLevel::TABLE); // this works
$table->foreign("level")->references("level")->on(Model\RealNationalLeagueLevel::TABLE); // this does not
});
}
Running the migration does not work. It throws QueryException:
SQLSTATE[HY000]: General error: 1005 Can't create table `testdb`.`#sql-17a00_448a37` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `real_national_league` add constraint `real_national_league_level_foreign` foreign key (`level`) references `real_national_league_level` (`level`))
Any idea why it's not working? Thanks for any help.
The table that you want to reference, you have to create it first, then in another migration, create a column from this table to that reference table.
I am trying to drop the foreign key and add the foreign key in one migration but can't get it to work:
I have created the table contents with the foreign key cms_id:
public function up()
{
Schema::create('contents', function (Blueprint $table) {
$table->increments('id');
$table->integer('ct_id')->unsigned();
$table->foreign('ct_id')->references('id')->on('content_types');
$table->integer('cms_id')->unsigned();
$table->foreign('cms_id')->references('id')->on('inventories');
$table->string('title');
$table->string('slug');
$table->text('excerpt');
$table->mediumText('body');
$table->string('password');
$table->integer('parent_id');
$table->timestamps();
});
}
This is how the inventories table looks like:
Schema::create('inventories', function (Blueprint $table) {
$table->increments('id');
$table->integer('remote_id');
$table->integer('local_id')->unsigned();
$table->string('local_type');
$table->timestamps();
});
And after failing to drop it and to create a new foreign key, I have deleted all the tables in the DB, and have tried to run all the migrations again with the new one as well, which holds this:
public function up()
{
Schema::table('inventories', function (Blueprint $table) {
$table->integer('remote_id')->unsigned()->change();
});
Schema::table('contents', function (Blueprint $table) {
$table->dropForeign('contents_cms_id_foreign');
$table->foreign('cms_id')->references('remote_id')->on('inventories');
});
Schema::table('files', function (Blueprint $table) {
$table->dropForeign('files_cms_id_foreign');
$table->foreign('cms_id')->references('remote_id')->on('inventories');
});
}
But,I get:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
(SQL : alter table contents add constraint
contents_cms_id_foreign foreign k ey (cms_id) references
inventories (remote_id))
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
If, I first run all the migrations where I create all the tables, and then after that run the new migration where I change the foreign keys, I get this error:
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP
'content s_cms_id_foreign'; check that column/key exists (SQL:
alter table contents drop foreign key
contents_cms_id_foreign)
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP
'content s_cms_id_foreign'; check that column/key exists
I have even tried to just delete all the tables in the DB, and only edit the files that I already have by just changing, without new migrations:
$table->integer('ct_id')->unsigned();
$table->foreign('ct_id')->references('remote_id')->on('content_types');
$table->integer('cms_id')->unsigned();
$table->foreign('cms_id')->references('remote_id')->on('inventories');
And, also in the inventories table:
$table->integer('remote_id')->unsigned();
But, even then it won't work, and I get:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
(SQL : alter table contents add constraint
contents_cms_id_foreign foreign k ey (cms_id) references
inventories (remote_id))
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
So, I have checked all of the usual suspects that I have come across on the internet, I have even added $table->engine = 'InnoDB'; to to the tables inventories, contents and files, I have made sure to first create tables and then add foreign keys, as well as checked if the columns have the same data type, not sure what to do else?
I'm using laravel to migrate some data, but i'm having this message below:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table 'heinz.#sql-1e83_8' (errno: 150) (SQL: alter table `funcionarios` add constraint funcionarios_supervisor_id_foreign foreign key (`supervis
or_id`) references `funcionarios` (`id`))
I tried a lot of thing, but didn't work.
Here is the code of the migration file. (the relevant part).
Schema::create('funcionarios', function (Blueprint $table) {
// $table->engine = 'InnoDB';
$table->increments('id');
$table->string('nome', 60);
$table->integer('matricula')->unsigned()->unique();
$table->bigInteger('pis_pasep')->unsigned()->nullable();
$table->date('data_admissao')->nullable();
$table->date('data_demissao')->nullable()->default(null);
$table->date('data_nascimento')->nullable();
$table->string('apelido', 20)->nullable();
$table->integer('supervisor_id')->nullable();
$table->integer('coordenador_id')->nullable();
$table->integer('gerente_id')->nullable();
$table->integer('diretor_id')->nullable();
$table->integer('sexo_id')->nullable();
$table->integer('setor_id')->nullable();
$table->integer('cargo_id');
$table->integer('turno_id')->nullable();
$table->timestamps();
});
Schema::table('funcionarios', function($table){
$table->foreign('supervisor_id')->references('id')->on('funcionarios');
$table->foreign('coordenador_id')->references('id')->on('funcionarios');
$table->foreign('gerente_id')->references('id')->on('funcionarios');
$table->foreign('diretor_id')->references('id')->on('funcionarios');
$table->foreign('sexo_id')->references('id')->on('sexos');
$table->foreign('setor_id')->references('id')->on('setores');
$table->foreign('cargo_id')->references('id')->on('cargos');
$table->foreign('turno_id')->references('id')->on('turnos');
});
All of your foreign keys must be unsigned
$table->integer('supervisor_id')->unsigned()->nullable();
$table->integer('coordenador_id')->unsigned()->nullable();
$table->integer('gerente_id')->unsigned()->nullable();
$table->integer('diretor_id')->unsigned()->nullable();
$table->integer('sexo_id')->unsigned()->nullable();
$table->integer('setor_id')->unsigned()->nullable();
$table->integer('cargo_id')->unsigned();
$table->integer('turno_id')->unsigned()->nullable();
(source: http://laravel.com/docs/4.2/schema#foreign-keys)
Without seeing your table structure, from your below query it could be that
both column id and supervisor_id doesn't match datatype and size. Make sure both datatype and size are same for both this column
Also, check if any other constraint with name funcionarios_supervisor_id_foreign already exists. If so, try providing a different name for the constraint.
alter table `funcionarios` add constraint funcionarios_supervisor_id_foreign
foreign key (`supervisor_id`) references `funcionarios` (`id`)
You get error code 1005 when there is a wrong primary key reference in your code. Here is what you can do to debug your code:
Make sure that your FK you are referring actually exists.
Make sure that you don't have typo. The case must be same too.
FK-linked fields must match definitions exactly.
The execution order of the migration files needs to be checked first. the referenced table migration should be done before refer it in integrity constains.
Why do I have a problem creating a table using Laravel Migrations Schema Builder?
The problem occurs with a table with a self-referencing foreign key.
Schema::create('cb_category', function($table)
{
$table->integer('id')->primary()->unique()->unsigned();
$table->integer('domain_id')->unsigned();
$table->foreign('domain_id')->references('id')->on('cb_domain');
$table->integer('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
$table->string('name');
$table->integer('level');
});
SQLSTATE[HY000]: General error: 1005 Can't create table 'eklik2.#sql-7d4_e' (errno: 150) (SQL: alter table `cb_category` add constraint cb_category_parent_id_foreign foreign key (`parent_id`) references `cb_category` (`id`) on delete cascade on update cascade) (Bindings: array ())
[PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create table 'eklik2.#sql-7d4_e' (errno: 150)
You have to break this into two Schema blocks, one creating the columns, the other adding the FKs. mysql can't do both at the same time.
Two querys work :
Schema::create('cb_category', function($table)
{
$table->integer('id')->primary()->unique()->unsigned();
$table->integer('parent_id')->nullable();
});
Schema::table('cb_category', function (Blueprint $table)
{
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
});
I may be too late for the party, but the official docs claim that the foreign key, in case of integer, must be ->unsigned();
http://laravel.com/docs/4.2/schema#foreign-keys
Note: When creating a foreign key that references an incrementing
integer, remember to always make the foreign key column unsigned.
Also, Artisan does not fail if you (as I have) misspell unsigned() and I have spent quite a few hours trying to figure out why the key was not created.
So two things:
1. Always make the foreign key column unsigned in case of incrementing integers
2. Check the spelling of unsigned()
Also a late response but probably a more idiomatic way for Laravel 8:
use App\Models\CbCategory;
...
Schema::create("cb_category", function(Blueprint $table)
{
$table->id();
$table->foreignIdFor(CbCategory::class, "parent_id")
->constrained()
->cascadeOnUpdate()
->cascadeOnDelete()
->nullable();
});
Please Note: I guessed the class name of CbCategory here. Using the class reference firsthand (instead of the former table name string) enables your static code checkers to pick up on future class name changes.
Also the _id-suffix at the parent_id column name is important.
May the following resources quench your thirst for knowledge:
id(): https://laravel.com/docs/8.x/migrations#column-method-id
foreignIdFor(): https://laravel.com/api/8.x/Illuminate/Database/Schema/Blueprint.html
cascadeOnDelete() & cascadeOnUpdate(): https://laravel.com/api/8.x/Illuminate/Database/Schema/ForeignKeyDefinition.html
Schema::create('cb_category', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('domain_id')->unsigned();
$table->foreign('domain_id')->references('id')->on('cb_domain');
$table->integer('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
$table->string('name');
$table->integer('level');
});
Try this
I think you have another table that references the current table that you want to create.
I had this problem and remove that table and my problem was solved
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->integer('parent_id')->unsigned();
$table->foreign('parent_id')->on('categories')->references('id');
});
i got same error when i used this code, after change "$table->integer('parent_id')->unsigned()" to "$table->bigInteger('parent_id');"
my problem solved.
The point here is to make sure that the type of foreign key is the same as the primary key.
Since Laravel 8+ you don't have to break into two Schema blocks. You can use
foreignIdFor(CbCategory::class, 'cb_category_id') and it will create a column named cb_category_id
Ex.
Schema::create("cb_category", function(Blueprint $table)
{
$table->id();
$table->foreignIdFor(CbCategory::class, 'cb_category_id')->nullable()->constrained()->cascadeOnUpdate()->cascadeOnDelete();
});
Any additional column modifiers (Ex. nulleable) must be called before the constrained method.
You can use a second parameter in foreignIdFor for the referencing column name (in case it isn't 'id') NOT for the name you want it to have, in your case the name will automatically be 'cb_category_id'