विदेशी कुंजी के साथ स्तंभ को छोड़ना Laravel त्रुटि: सामान्य त्रुटि: नाम बदलने पर 1025 त्रुटि


94

मैंने इस तरह माइग्रेशन का उपयोग करके एक तालिका बनाई है:

public function up()
{
    Schema::create('despatch_discrepancies',  function($table) {
        $table->increments('id')->unsigned();
        $table->integer('pick_id')->unsigned();
        $table->foreign('pick_id')->references('id')->on('picks');
        $table->integer('pick_detail_id')->unsigned();
        $table->foreign('pick_detail_id')->references('id')->on('pick_details');
        $table->integer('original_qty')->unsigned();
        $table->integer('shipped_qty')->unsigned();
    });
}

public function down()
{
    Schema::drop('despatch_discrepancies');
}

मुझे इस तालिका को बदलने और विदेशी कुंजी संदर्भ और कॉलम को छोड़ने और कॉलम के बाद pick_detail_idएक नया वर्चर कॉलम जोड़ने की आवश्यकता है ।skupick_id

तो, मैंने एक और प्रवास बनाया है, जो इस तरह दिखता है:

public function up()
{
    Schema::table('despatch_discrepancies', function($table)
    {
        $table->dropForeign('pick_detail_id');
        $table->dropColumn('pick_detail_id');
        $table->string('sku', 20)->after('pick_id');
    });
}

public function down()
{
    Schema::table('despatch_discrepancies', function($table)
    {
        $table->integer('pick_detail_id')->unsigned();
        $table->foreign('pick_detail_id')->references('id')->on('pick_details');
        $table->dropColumn('sku');
    });
}

जब मैं इस माइग्रेशन को चलाता हूं, तो मुझे निम्न त्रुटि मिलती है:

[Illuminate \ Database \ QueryException]
SQLSTATE [HY000]: सामान्य त्रुटि: 'के नाम पर 1025 त्रुटि ।/dev_iwms_reboot/despatch_discreparios' पर ।/dev_iwms_reboot/#sql2-67c-17c464 '(152: 152) despatch_discrepanciesड्रॉप विदेशी कुंजी pick_detail_id)

[PDOException]
SQLSTATE [HY000]: सामान्य त्रुटि: '25 ./dev_iwms_reboot/despatch_discrepancies 'का नाम बदलने के लिए' ./dev_iwms_reboot/#sql2-67c-1764 '(इरनो): 152 पर त्रुटि।

जब मैं php artisan migrate:rollbackकमांड चलाकर इस माइग्रेशन को उलटने की कोशिश करता हूं, तो मुझे एक Rolled backसंदेश मिलता है , लेकिन यह वास्तव में डेटाबेस में कुछ भी नहीं कर रहा है।

किसी भी विचार क्या गलत हो सकता है? आप उस कॉलम को कैसे छोड़ सकते हैं जिसमें एक विदेशी कुंजी संदर्भ है?

जवाबों:


167

आप इसका उपयोग कर सकते हैं:

$table->dropForeign(['pick_detail_id']);
$table->dropColumn('pick_detail_id');

यदि आप ड्रॉप-डाउन स्रोत पर एक चोटी लेते हैं, तो यह आपके लिए विदेशी कुंजी इंडेक्स नाम का निर्माण करेगा यदि आप एक कॉलम के रूप में कॉलम नाम से गुजरते हैं।


2
स्वीकृत उत्तर भी काम करता है: आपको सही सूचकांक नाम सम्मेलन का उपयोग करना होगा। लेकिन उस उत्तर के साथ भी यही समस्या है: आपको इंडेक्स के लिए नामकरण योजना को याद रखना होगा, जबकि यह समाधान इसे स्वचालित रूप से करता है! मैंने हमेशा दूसरे तरीके का इस्तेमाल किया, और हमेशा शिकायत की कि यह कितना अव्यावहारिक था। अब मैं तुरंत इस समाधान पर जा रहा हूं। आपका बहुत बहुत धन्यवाद!
मार्को पलांटे

6
बहुत बढ़िया चाल। मैं इसे चूसने वाले की तरह लंबा कर रहा हूं। लारवेल वास्तव में डॉक्स पर कुछ मदद का उपयोग कर सकता है। मैं चुनौती ले सकता हूं ...
सिमोनहम्प

1
मेरे लिए Laravel 5.0 में काम किया। बहुत बहुत धन्यवाद, एलेक्स!

1
लारावेल 5.2 में एक आकर्षण की तरह काम किया।
रोनिन

3
यह एक साफ सुथरी चाल है। विदेशी प्रमुख नामकरण सम्मेलन (जो भविष्य में बदल सकता है) को याद करने से बेहतर है। जैसे @ ronin1184 ने कहा, लारावेल 5.2 में पूरी तरह से काम करता है
रॉबिन वैन बालन

81

यह पता चला है; जब आप इस तरह एक विदेशी कुंजी बनाते हैं:

$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');

लारवेल ने विशिष्ट रूप से इस तरह के विदेशी संदर्भ को नाम दिया:

<table_name>_<foreign_table_name>_<column_name>_foreign
despatch_discrepancies_pick_detail_id_foreign (in my case)

इसलिए, जब आप विदेशी कुंजी संदर्भ के साथ एक कॉलम ड्रॉप करना चाहते हैं, तो आपको इसे इस तरह करना होगा:

$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign');
$table->dropColumn('pick_detail_id');

अपडेट करें:

लारवेल 4.2+ एक नया नामकरण सम्मेलन पेश करता है:

<table_name>_<column_name>_foreign

4
लारावेल 4.2 में काम नहीं करता है। <Foreign_table_name> कुंजी नाम का हिस्सा नहीं है। यह सिर्फ <table_name> _ <column_name> _foreign के साथ काम करता है।
अमीर रईस

मैंने इसे लार्वा 4.2 में इस्तेमाल किया और अभी भी करता हूं, यह मेरे लिए काम करता है।
रात्रि

2
<table_name>_<column_name>_foreignसम्मेलन अभी भी 5.1 के लिए काम करने के लिए लगता है
याह्या उद्दीन

जाहिरा तौर पर, रिश्ते पर बाधा को छोड़ने के बाद, आपको स्तंभ भी छोड़ना होगा। मुझे लगता है कि दस्तावेज़ीकरण में इसे भी शामिल किया जाना चाहिए क्योंकि कोई आसानी से मान सकता है ड्रॉपऑर्गिन कॉलम को भी हटा देगा। साझा करने के लिए धन्यवाद। laravel.com/docs/5.0/schema#dropping-columns
Picrasma

यदि कोई सोच रहा था, तो कॉलम के होने पर MySQL स्वचालित रूप से विदेशी कुंजियों के लिए बनाता है। उन्हें मैन्युअल रूप से छोड़ने की आवश्यकता नहीं है $table->dropIndex('column_name')
अलेक्जेंडर

24

मेरी तालिका में कई विदेशी कुंजियाँ थीं और फिर मुझे नीचे की विधि में सरणी के सूचकांक के रूप में कॉलम नाम से गुजरते हुए एक-एक करके विदेशी कुंजी बाधाओं को हटाना पड़ा:

public function up()
{
    Schema::table('offices', function (Blueprint $table) {
        $table->unsignedInteger('country_id')->nullable();
        $table->foreign('country_id')
            ->references('id')
            ->on('countries')
            ->onDelete('cascade');

        $table->unsignedInteger('stateprovince_id')->nullable();
        $table->foreign('stateprovince_id')
            ->references('id')
            ->on('stateprovince')
            ->onDelete('cascade');
        $table->unsignedInteger('city_id')->nullable();
        $table->foreign('city_id')
            ->references('id')
            ->on('cities')
            ->onDelete('cascade');
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::table('offices', function (Blueprint $table) {
        $table->dropForeign(['country_id']);
        $table->dropForeign(['stateprovince_id']);
        $table->dropForeign(['city_id']);
        $table->dropColumn(['country_id','stateprovince_id','city_id']);
    });
} 

नीचे दिए गए कथन का उपयोग करने से काम नहीं चलता है

$table->dropForeign(['country_id','stateprovince_id','city_id']); 

क्योंकि dropForeign उन्हें अलग स्तंभों पर विचार नहीं करता है जिन्हें हम निकालना चाहते हैं। इसलिए हमें उन्हें एक-एक करके छोड़ना होगा।


मेरे मित्र को धन्यवाद, एक सरणी में कॉलम नाम जोड़ना मेरे लिए काम करता है।
पियरे

यदि कोई सोच रहा था, तो कॉलम के होने पर MySQL स्वचालित रूप से विदेशी कुंजियों के लिए बनाता है। उन्हें मैन्युअल रूप से छोड़ने की आवश्यकता नहीं है $table->dropIndex('column_name')
अलेक्जेंडर

9

इसे हल करने के लिए कुंजी (मेरे लिए) यह सुनिश्चित करने के लिए थी कि $ तालिका-> ड्रॉपफॉरइन () कमांड सही रिश्ते का नाम पारित किया जा रहा था, जरूरी नहीं कि स्तंभ नाम। आप कॉलम नाम को पारित नहीं करना चाहते हैं, क्योंकि यह बहुत अधिक सहज IMHO होगा।

मेरे लिए क्या काम था:

$table->dropForeign('local_table_foreign_id_foreign');
$table->column('foreign_id');

तो मैं ड्रॉप करने के लिए पारित स्ट्रिंग () कि मेरे लिए काम किया था के प्रारूप में था:

[स्थानीय तालिका] _ [विदेशी कुंजी क्षेत्र] _foreign

यदि आपके पास Sequel Pro या Navicat जैसे उपकरण तक पहुंच है, तो कल्पना करने में सक्षम होना बहुत मददगार होगा।


यह ठीक काम करता है, मैंने पाया कि इसे कोष्ठक में तालिका के आसपास की तुलना में कम सहज होना चाहिए जैसा कि @ एलेक्स ने सुझाव दिया था।
मार्क करावन

5

मेरे साथ कुछ ऐसा हुआ था कि मुझे नहीं पता था कि Schema::tableब्लॉक कहां लगाया जाए ।

बाद में मुझे पता चला कि कुंजी SQL त्रुटि पर है:

[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table if exists `lu_benefits_categories`)

इसलिए Schema::tableब्लॉक down()को lu_benefits_categoriesप्रवास के कार्य में और Schema::dropIfExistsलाइन से पहले जाने की आवश्यकता है :

public function down()
{
    Schema::table('table', function (Blueprint $table) {
        $table->dropForeign('table_category_id_foreign');
        $table->dropColumn('category_id');
    });
    Schema::dropIfExists('lu_benefits_categories');
}

उसके बाद, php artisan migrate:refreshया php artisan migrate:resetचाल चलेंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.