Saya mencoba membuat kunci asing di Laravel namun ketika saya memigrasikan meja saya menggunakan artisan
saya terlempar kesalahan berikut:
[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`))
Kode migrasi saya demikian:
file migrasi prioritas
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');
}
file migrasi pengguna
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');
}
Setiap gagasan tentang apa yang telah saya lakukan salah, saya ingin mendapatkan ini sekarang, karena saya punya banyak tabel yang perlu saya buat misalnya Pengguna, Klien, Proyek, Tugas, Status, Prioritas, Jenis, Tim. Idealnya saya ingin membuat tabel yang menyimpan data ini dengan kunci asing, i..e clients_project
dan project_tasks
lain - lain
Semoga seseorang dapat membantu saya memulai.
Schema::table
metode membantu! Terima kasih!$table->unsignedBigInteger('user_id')
jika user.id AndabigIncrements
Pertanyaan sudah dijawab, tetapi harap ini bisa membantu orang lain.
Kesalahan ini terjadi pada saya karena saya membuat tabel migrasi dengan kunci asing di dalamnya terlebih dahulu sebelum kunci tersebut ada sebagai kunci utama di tabel aslinya. Migrasi dieksekusi dalam urutan seperti yang ditunjukkan oleh nama file yang dihasilkan setelah dijalankan
migrate:make
. Misalnya2014_05_10_165709_create_student_table.php
.Solusinya adalah mengubah nama file dengan kunci asing ke waktu yang lebih awal daripada file dengan kunci utama seperti yang direkomendasikan di sini: http://forumsarchive.laravel.io/viewtopic.php?id=10246
Saya pikir saya juga harus menambahkan
$table->engine = 'InnoDB';
sumber
Laravel ^ 5.8
Contoh
Bayangkan Anda sedang membangun aplikasi berbasis peran sederhana, dan Anda perlu mereferensikan user_id di tabel PIVOT "role_user" .
2019_05_05_112458_create_users_table.php
2019_05_05_120634_create_role_user_pivot_table.php
Seperti yang Anda lihat, baris yang dikomentari akan mengeluarkan pengecualian permintaan, karena, seperti yang disebutkan dalam catatan pemutakhiran, kolom kunci asing harus dari jenis yang sama , oleh karena itu Anda perlu mengubah kunci foreing (dalam contoh ini adalah user_id ) untuk bigInteger di tabel role_user atau ubah metode bigIncrements menjadi metode penambahan di tabel pengguna dan gunakan baris yang dikomentari di tabel pivot, terserah Anda.
Saya harap saya bisa mengklarifikasi masalah ini kepada Anda.
sumber
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'); }
Itu berhasil. Terima kasih.Dalam kasus saya, masalahnya adalah bahwa tabel utama sudah memiliki catatan di dalamnya dan saya memaksa kolom baru untuk tidak NULL. Jadi menambahkan -> nullable () ke kolom baru berhasil. Dalam contoh pertanyaan adalah kira-kira seperti ini:
$table->integer('user_id')->unsigned()->nullable();
atau:
$table->unsignedInteger('user_id')->nullable();
Semoga ini bisa membantu seseorang!
sumber
Dalam kasus saya masalahnya adalah bahwa migrasi yang dibuat secara otomatis untuk
users
tabel diaturJadi saya harus mengubah jenis kolom
untuk membuat migrasi saya dengan kunci asing berfungsi.
Ini dengan laravel
5.8.2
sumber
Dalam kasus saya masalahnya adalah waktu migrasi berhati-hati saat membuat migrasi terlebih dahulu buat migrasi anak daripada migrasi dasar. Karena jika Anda membuat migrasi basis pertama yang memiliki kunci asing Anda akan mencari tabel anak dan tidak akan ada tabel yang kemudian melemparkan pengecualian.
Selanjutnya:
Saat Anda membuat migrasi, ia memiliki cap waktu di awal. katakanlah Anda telah membuat kucing migrasi sehingga akan terlihat seperti
2015_08_19_075954_the_cats_time.php
dan memiliki kode iniDan setelah membuat tabel dasar Anda membuat jenis migrasi lain yang merupakan tabel anak itu memiliki waktu pembuatan dan cap tanggal sendiri. Kode akan terlihat seperti:
tampaknya kedua tabel ini benar tetapi ketika Anda menjalankan php artisan migrasi . Ini akan mengeluarkan pengecualian karena migrasi pertama akan membuat tabel dasar dalam database Anda karena Anda telah membuat migrasi ini terlebih dahulu dan tabel dasar kami memiliki batasan kunci asing di dalamnya yang akan mencari tabel anak dan tabel anak tidak ada yang mungkin ada pengecualian ..
Begitu:
melakukannya akan berhasil
sumber
Dalam kasus saya, saya hanya mengubah urutan migrasi yang dieksekusi secara manual sehingga pengguna tabel dibuat terlebih dahulu.
Dalam database folder / migrasi / nama file migrasi Anda memiliki format ini: year_month_day_hhmmss_create_XXXX_table.php
Cukup ganti nama buat file pengguna sehingga tanggal pembuatan tabel prioritas tabel Anda ditetapkan lebih lambat dari tanggal pengguna (bahkan satu detik kemudian sudah cukup)
sumber
Di laravel 5.8, users_table menggunakan
bigIncrements('id')
tipe data untuk kunci utama. Sehingga ketika Anda ingin merujuk batasan kunci asinguser_id
kolom Anda harusunsignedBigInteger('user_id')
mengetik.sumber
Saya mengalami masalah yang sama menggunakan Laravel 5.8. Setelah melihat lebih dekat ke dokumen laravel, apalagi di sini Migrasi & Instalasi Besar . Cara saya menyelesaikannya adalah dengan menambahkan kunci primer "$ table-> bigIncrements ('id')" ke setiap tabel yang terkait dengan tabel "pengguna" dan asosiasinya, dalam kasus saya tabel "peran" . Terakhir, saya memiliki "$ table-> unsignedBigInteger" untuk mengaitkan peran dengan pengguna (Banyak ke Banyak), yaitu, tabel "role_user" .
sumber
Saya punya masalah dengan laravel 5.8 dan saya memperbaiki kode ini, seperti yang ditunjukkan di sini dalam dokumentasi Laravel , di mana pun saya menambahkan kunci asing.
lalu aku berlari
$ php artisan migrate:refresh
Karena sintaks ini agak bertele-tele, Laravel menyediakan metode terser tambahan yang menggunakan konvensi untuk memberikan pengalaman pengembang yang lebih baik. Contoh di atas dapat ditulis seperti ini:
sumber
Menggunakan Laravel 5.3 memiliki masalah yang sama.
Solusinya adalah menggunakan unsignedInteger alih-alih integer ('name') -> unsigned () .
Jadi ini yang berhasil
Alasan ini berhasil adalah kenyataan bahwa ketika menggunakan integer ('name') -> unsigned kolom yang dibuat dalam tabel memiliki panjang 11, tetapi ketika menggunakan unsigedInteger ('name') kolom tersebut memiliki panjang 10.
Panjang 10 adalah panjang untuk kunci utama saat menggunakan Laravel sehingga panjang kolom cocok.
sumber
Kesalahan ini terjadi pada saya karena - sementara tabel yang saya coba buat adalah InnoDB - tabel asing yang saya coba kaitkan dengannya adalah tabel MyISAM!
sumber
Kami tidak dapat menambahkan hubungan, kecuali tabel terkait dibuat. Laravel menjalankan pesanan migrasi berdasarkan tanggal file migrasi. Jadi jika Anda ingin membuat hubungan dengan tabel yang ada di file migrasi ke-2, gagal.
Saya menghadapi masalah yang sama, jadi saya membuat satu file migrasi lagi untuk menentukan semua hubungan.
sumber
Berhati-hatilah: saat Laravel menyiapkan tabel menggunakan
yang merupakan standar di sebagian besar migrasi, ini akan mengatur bidang bilangan bulat yang tidak ditandatangani. Oleh karena itu saat membuat referensi asing dari tabel lain ke bidang ini, pastikan bahwa dalam tabel referensi, Anda menetapkan bidang ke UnsignedInteger dan bukan (yang saya anggap sebagai) bidang UnsignedBigInteger.
Misalnya: di file migrasi 2018_12_12_123456_create_users_table.php:
Kemudian di file migrasi 2018_12_12_18000000_create_permissions_table.php, yang mengatur referensi asing kembali ke pengguna:
sumber
Anda harus menulis dengan cara ini
Bidang kunci asing harus ditandatangani , semoga membantu !!
sumber
Untuk membuat penambahan batasan kunci asing di laravel, berikut ini bekerja untuk saya:
Buat kolom menjadi kunci asing sebagai berikut:
Menambahkan garis kendala segera setelah (1) yaitu
sumber
Saya tahu itu pertanyaan lama tetapi pastikan jika Anda bekerja dengan referensi mesin pendukung yang tepat didefinisikan. atur mesin innodb untuk kedua tabel dan tipe data yang sama untuk kolom referensi
sumber
Menjebak di sini beberapa tahun setelah pertanyaan awal, menggunakan laravel 5.1, saya memiliki kesalahan yang sama dengan migrasi saya yang dihasilkan komputer dengan semua kode tanggal yang sama. Saya memeriksa semua solusi yang diusulkan, kemudian refactored untuk menemukan sumber kesalahan.
Dalam laracasts berikut, dan dalam membaca posting ini, saya percaya jawaban yang benar mirip dengan jawaban Vickies, dengan pengecualian bahwa Anda tidak perlu menambahkan panggilan skema terpisah. Anda tidak perlu mengatur meja ke Innodb, saya berasumsi laravel sekarang melakukan itu.
Migrasi hanya perlu diatur waktunya dengan benar, yang berarti Anda akan mengubah kode tanggal naik (nanti) dalam nama file untuk tabel di mana Anda memerlukan kunci asing. Atau sebagai tambahan, Turunkan datecode untuk tabel yang tidak memerlukan kunci asing.
Keuntungan dalam memodifikasi datecode adalah kode migrasi Anda akan lebih mudah dibaca dan dipelihara.
Sejauh ini kode saya berfungsi dengan menyesuaikan kode waktu ke atas untuk mendorong kembali migrasi yang memerlukan kunci asing.
Namun saya punya ratusan meja, jadi pada akhirnya saya punya satu meja terakhir hanya untuk kunci asing. Hanya untuk membuat segalanya mengalir. Saya berasumsi saya akan menarik mereka ke file yang benar dan memodifikasi datecode saat saya mengujinya.
Jadi contoh: file 2016_01_18_999999_create_product_options_table. Yang ini membutuhkan tabel produk yang akan dibuat. Lihatlah nama file.
tabel produk: ini perlu dimigrasi dulu. 2015_01_18_000000_create_products_table
Dan akhirnya di bagian paling akhir file yang saya gunakan sementara untuk menyelesaikan masalah, yang akan saya refactor ketika saya menulis tes untuk model yang saya beri nama 9999_99_99_999999_create_foreign_keys.php. Kunci-kunci ini dikomentari ketika saya mengeluarkannya, tetapi Anda mengerti maksudnya.
sumber
Sangat sederhana !!!
jika Anda pertama kali membuat
'priorities'
file migrasi, Laravel jalankan dulu'priorities'
sementara'users'
tabel tidak ada.bagaimana bisa menambahkan relasi ke tabel yang tidak ada !.
Solusi: mengeluarkan kode kunci asing dari
'priorities'
tabel. file migrasi Anda harus seperti ini:dan tambahkan ke file migrasi baru, ini namanya
create_prioritiesForeignKey_table
dan tambahkan kode-kode ini:sumber
pastikan kolom foreing Anda lebih luas dari foreing key key
Maksud saya foreingkey Anda (di tabel kedua) harus sama jenis kunci pricipal ponter Anda (di tabel pertama)
kunci utama penunjuk Anda harus ditambahkan metode yang tidak ditandatangani, izinkan saya menunjukkan:
pada tabel migrasi PERTAMA Anda:
pada tabel migrasi KEDUA Anda:
CONTOH LAIN UNTUK MELIHAT PERBEDAAN
pada tabel migrasi PERTAMA Anda:
pada tabel migrasi KEDUA Anda:
MELIHAT MYSQL NUMERIC TYPE TABLE RANGES
sumber
Satu hal yang saya perhatikan adalah bahwa jika tabel menggunakan mesin yang berbeda dari batasan kunci asing tidak berfungsi.
Misalnya jika satu tabel menggunakan:
Dan kegunaan lainnya
akan menghasilkan kesalahan:
Anda bisa memperbaikinya dengan hanya menambahkan InnoDB di akhir pembuatan tabel Anda seperti:
sumber
Dalam kasus saya, saya mereferensikan kolom integer
id
pada kolom stringuser_id
. Aku berubah:$table->string('user_id')
untuk:
$table->integer('user_id')->unsigned();
Semoga ini bisa membantu seseorang!
sumber
Intinya adalah bahwa metode asing digunakan
ALTER_TABLE
untuk membuat bidang yang sudah ada menjadi kunci asing. Jadi, Anda harus menentukan tipe tabel sebelum Anda menerapkan kunci asing. Namun, itu tidak harus dalamSchema::
panggilan terpisah . Anda dapat melakukan keduanya di dalam buat, seperti ini:Perhatikan juga bahwa tipe
user_id
diset ke unsigned agar cocok dengan kunci asing.sumber
Anda dapat langsung melewati parameter boolean di kolom integer yang mengatakan bahwa itu harus tidak ditandatangani atau tidak. Di laravel 5.4 kode berikut memecahkan masalah saya.
Di sini parameter kedua false menyatakan bahwa seharusnya tidak bertambah secara otomatis dan parameter ketiga true menyatakan bahwa seharusnya tidak ditandatangani. Anda dapat menjaga batasan kunci asing dalam migrasi yang sama atau memisahkannya. Ini bekerja pada keduanya.
sumber
Jika tidak ada solusi di atas yang berfungsi untuk pemula, periksa apakah kedua ID memiliki tipe yang sama: keduanya
integer
atau keduanyabigInteger
, ... Anda dapat memiliki sesuatu seperti ini:Tabel Utama (pengguna misalnya)
Meja Anak (prioritas misalnya)
Kueri ini akan gagal karena
users.id
merupakanBIG INTEGER
sedangkanpriorities.user_id
adalahINTEGER
.Kueri yang tepat dalam kasus ini adalah sebagai berikut:
sumber
Dalam kasus saya itu tidak berfungsi sampai saya menjalankan perintah
dengan begitu Anda bisa meninggalkan kunci asing di dalam Skema buat
sumber
Mungkin juga Anda memesan migrasi kreasi. Jika Anda pertama kali membuat tabel prioritas, dan setelah tabel pengguna maka itu akan salah. Karena migrasi pertama mencari tabel pengguna. Jadi, Anda harus mengubah urutan migrasi
direktori
sumber
Bagi saya, kolom tabel yang direferensikan oleh tabel anak saya tidak diindeks.
Abaikan penamaan yang mengerikan, itu dari sistem lain yang dirancang sangat.
sumber
Beberapa kali kesalahan ini dapat terjadi karena urutan migrasi.
Seperti Pengguna dan Pesanan adalah dua tabel
Tabel pesanan memiliki kunci asing pengguna (Selama migrasi jika Tabel pesanan dimigrasi terlebih dahulu maka itu akan menyebabkan masalah karena tidak ada pengguna yang cocok dengan kunci asing)
Solusi: Taruh saja tabel Pembaruan Pesanan di bawah pengguna untuk pembaruan
Contoh: Dalam kasus saya Tabel Pendidikan dan Universitas Tabel Pendidikan
Di Universitas
sumber
Satu hal yang menurut saya hilang dari jawaban di sini, dan tolong perbaiki saya jika saya salah, tetapi kunci asing perlu diindeks pada tabel pivot. Setidaknya dalam mysql yang tampaknya menjadi masalah.
sumber