लारवेल प्रवासन एक स्तंभ अशक्त बनाने के लिए बदलें


194

मैंने अहस्ताक्षरित के साथ एक माइग्रेशन बनाया user_id। मैं user_idइसे बनाने के लिए एक नए माइग्रेशन में कैसे संपादित कर सकता हूं nullable()?

Schema::create('throttle', function(Blueprint $table)
{
    $table->increments('id');
    // this needs to also be nullable, how should the next migration be?
    $table->integer('user_id')->unsigned();
}

जवाबों:


263

लारवेल 5 अब एक कॉलम को बदलने का समर्थन करता है; यहाँ एक उदाहरण है दस्तावेज़ीकरण से:

Schema::table('users', function($table)
{
    $table->string('name', 50)->nullable()->change();
});

स्रोत: http://laravel.com/docs/5.0/schema#changing-columns

लारवेल 4 कॉलम को संशोधित करने का समर्थन नहीं करता है, इसलिए आपको एक अन्य तकनीक का उपयोग करने की आवश्यकता होगी जैसे कि एक कच्चा एसक्यूएल कमांड लिखना। उदाहरण के लिए:

// getting Laravel App Instance
$app = app();

// getting laravel main version
$laravelVer = explode('.',$app::VERSION);

switch ($laravelVer[0]) {

    // Laravel 4
    case('4'):

        DB::statement('ALTER TABLE `pro_categories_langs` MODIFY `name` VARCHAR(100) NULL;');
        break;

    // Laravel 5, or Laravel 6
    default:                

        Schema::table('pro_categories_langs', function(Blueprint $t) {
            $t->string('name', 100)->nullable()->change();
        });               

}

3
इसके लिए Thx। लेकिन मैं इसके विपरीत कैसे बना सकता हूं? अशक्त न होने के लिए एक कॉलम कैसे बदलें? कोई विचार?
algorhythm

@algorhythm क्या आप यह '$ t-> स्ट्रिंग (' नाम ', 100) -> परिवर्तन ();
MURATSPLAT

7
आपको प्रवास के लिए सिद्धांत \ _ dbal की आवश्यकता है
younes0

33
@algorhythm ->nullable(false)आपको कॉलम को फिर से वापस बदलने देगा।
कॉलिन

9
-> परिवर्तन () के लिए आपको डॉक्ट्रिन डीबीएएल पैकेज स्थापित करने की आवश्यकता होती है, और यह स्वाभाविक रूप से सभी समान कॉलम प्रकारों को नहीं पहचानता है जो लार्वा से बॉक्स से बाहर उपलब्ध हैं .. उदाहरण के लिए डबल डीबीएएल के लिए एक मान्यता प्राप्त कॉलम प्रकार नहीं है।
विंसेंट

174

यहाँ भविष्य के पाठक के लिए पूर्ण उत्तर है। ध्यान दें कि यह केवल Laravel 5+ में संभव है।

सबसे पहले आपको सिद्धांत / सुस्त पैकेज की आवश्यकता होगी :

composer require doctrine/dbal

अब आप अपने माइग्रेशन में कॉलम को अशक्त बनाने के लिए ऐसा कर सकते हैं:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        // change() tells the Schema builder that we are altering a table
        $table->integer('user_id')->unsigned()->nullable()->change();
    });
}

आप सोच रहे होंगे कि इस ऑपरेशन को कैसे वापस किया जाए। अफसोस की बात है कि यह वाक्य रचना समर्थित नहीं है:

// Sadly does not work :'(
$table->integer('user_id')->unsigned()->change();

माइग्रेशन को वापस करने के लिए यह सही सिंटैक्स है:

$table->integer('user_id')->unsigned()->nullable(false)->change();

या, यदि आप चाहें, तो आप एक कच्चा प्रश्न लिख सकते हैं:

public function down()
{
    /* Make user_id un-nullable */
    DB::statement('UPDATE `users` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    DB::statement('ALTER TABLE `users` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

उम्मीद है कि आपको यह उत्तर उपयोगी लगेगा। :)


4
L5 के लिए यह सबसे पूर्ण उत्तर है, लेकिन यह उल्लेख किया जाना चाहिए कि यदि 'user_id' एक विदेशी कुंजी है, जो कि यह होनी चाहिए, तो आप इसे तब तक नहीं बदल पाएंगे, जब तक कि आप 'DB :: statement (' SET FOREIGN_KEY_CHECKS) न चला लें। = 0 ')?' प्रथम। और इसे 1 पर सेट करें जब आप कर लें।
rzb

1
धन्यवाद, nullable(false)मुझे अपने बालों को बाहर निकालने से बचाया, क्योंकि nullable()अच्छी तरह से प्रलेखित नहीं है, और कोई notNull()कार्य नहीं है।
ज़ैक मॉरिस

यह पोस्टग्रेज के साथ विदेशी कुंजी के लिए काम नहीं करता है। कोशिश करना SET FOREIGN_KEY_CHECKS = 0एक त्रुटि देता है। आपको कच्ची क्वेरी का उपयोग करके तालिका की बाधाओं को बदलने की संभावना होगी। यहाँ देखें: postgresql.org/docs/current/static/sql-altertable.html
rrrafalsz

यह मेरी परीक्षाओं को तोड़ रहा है। परीक्षण चलने लगते हैं और फिर लटक जाते हैं। मुझे लगता है कि यह पहला रोलबैक है। MySQL के साथ-साथ SQLite के लिए हैंगिंग टेस्ट का कारण बनता है।
थॉमस प्रॉक्स

155

मुझे लगता है कि आप एक स्तंभ को संपादित करने की कोशिश कर रहे हैं जिसे आपने पहले ही डेटा जोड़ दिया है, इसलिए स्तंभ को छोड़ देना और एक अशक्त स्तंभ के रूप में फिर से जोड़ना डेटा खोए बिना संभव नहीं है। कुंआalter मौजूदा कॉलम ।

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

function up()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
}

और यह सुनिश्चित करने के लिए कि आप अभी भी अपने माइग्रेशन को रोलबैक कर सकते हैं, हम भी ऐसा ही down()करेंगे।

function down()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

एक नोट यह है कि चूंकि आप अशक्त और अशक्त नहीं के बीच परिवर्तित कर रहे हैं, इसलिए आपको यह सुनिश्चित करने की आवश्यकता होगी कि आप अपने प्रवास से पहले / बाद में डेटा को साफ कर लें। तो अपने माइग्रेशन स्क्रिप्ट में दोनों तरीकों से ऐसा करें:

function up()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
    DB::statement('UPDATE `throttle` SET `user_id` = NULL WHERE `user_id` = 0;');
}

function down()
{
    DB::statement('UPDATE `throttle` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

7
Laravel 4 के लिए, की जगह queryसेstatement
उस्तरा

2
धन्यवाद @ रेजर। तदनुसार मेरे उत्तर को अपडेट करें।
उन्नाव

1
में downदूसरा कोड ब्लॉक में समारोह, एसक्यूएल बयान के साथ समाप्त होना चाहिए NOT NULL। ( downतीसरे उदाहरण में कार्य सही है।)
स्कॉट वेल्डन

46

वह लारावेल 5 के लिए पूर्ण प्रवास कर रहे हैं :

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedInteger('user_id')->nullable()->change();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedInteger('user_id')->nullable(false)->change();
    });
}

मुद्दा यह है, आप एक तर्क के रूप में nullableपारित करके निकाल सकते हैं false


16

यदि आप स्तंभों को बदलने और ठोकर खाने के लिए होते हैं

'Doctrine\DBAL\Driver\PDOMySql\Driver' not found

तो बस स्थापित करें

composer require doctrine/dbal


1
इस बिट ने मुझे इसलिए आगे बढ़ाया और इसके अपवाद / समाधान को आसान बना दिया: github.com/laravel/framework/pull/10002
Beau Simensen

9

लारावेल 5+ के अनुसार, दिमित्री चेबटेरेव के जवाब में जोड़ना।

सिद्धांत / सुस्त पैकेज की आवश्यकता के बाद :

composer require doctrine/dbal

फिर आप अशक्त स्तंभों के साथ माइग्रेशन कर सकते हैं, जैसे:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        // change() tells the Schema builder that we are altering a table
        $table->integer('user_id')->unsigned()->nullable()->change();
    });
}

ऑपरेशन को वापस करने के लिए, करें:

public function down()
{
    /* turn off foreign key checks for a moment */
    DB::statement('SET FOREIGN_KEY_CHECKS = 0');
    /* set null values to 0 first */
    DB::statement('UPDATE `users` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    /* alter table */
    DB::statement('ALTER TABLE `users` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
    /* finally turn foreign key checks back on */
    DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}

3

दिमित्री चेबोटरेव उत्तर में जोड़ना,

यदि आप एक बार में कई कॉलम बदलना चाहते हैं, तो आप इसे नीचे की तरह कर सकते हैं

DB::statement('
     ALTER TABLE `events` 
            MODIFY `event_date` DATE NOT NULL,
            MODIFY `event_start_time` TIME NOT NULL,
            MODIFY `event_end_time` TIME NOT NULL;
');

2

कोशिश करो:

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

1
यह मौजूदा कॉलम को परिवर्तित नहीं करता है
dVaffection

9
आप ->changeअंत में भूल गए और इसका उल्लेख लारावेल 5+ केवल
अलेक्जेंडर मालाखोव

आपको आवश्यकता हैcomposer require doctrine/dbal
लिजेश शाक्य

2

लारवेल 4.2 के लिए, ऊपर से उन्नाव का जवाब सबसे अच्छा है। लेकिन यदि आप तालिका उपसर्ग का उपयोग कर रहे हैं, तो आपको अपने कोड को थोड़ा बदलना होगा।

function up()
{
    $table_prefix = DB::getTablePrefix();
    DB::statement('ALTER TABLE `' . $table_prefix . 'throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
}

और यह सुनिश्चित करने के लिए कि आप अभी भी अपने माइग्रेशन को रोलबैक कर सकते हैं, हम भी ऐसा ही down()करेंगे।

function down()
{
    $table_prefix = DB::getTablePrefix();
    DB::statement('ALTER TABLE `' . $table_prefix . 'throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.