कुछ अति-इंजीनियर और अत्यधिक चतुर समाधान प्रयासों के बाद, मुझे लगता है कि निम्नलिखित समस्या का एक व्यावहारिक समाधान है।
टीएल; डॉ:
- माइग्रेशन के दोनों ओर माइग्रेशन बुक करें जो कुछ भी नहीं से स्कीमा बनाते हैं।
- प्रोजेक्ट अपडेट करें।
- माइग्रेट करें।
- बुकएंड और पिछले सभी माइग्रेशन हटाएं।
migrations
से रिकॉर्ड हटाएं मेज़।
पहला बुकएंड प्रभावित तालिकाओं का नाम बदलता है। दूसरा बुकएंड, पुनर्नामित तालिकाओं से डेटा को ताज़ा तालिकाओं में कॉपी करता है, फिर नामित तालिकाओं को हटा देता है।
नोट:आप बुकेंड के अंदर जो चाहें कर सकते हैं, यह केवल एक न्यूनतम है।
तो, चलिए आपको माइग्रेशन के लिए कुछ इस तरह कहते हैं:
- 2017_09_05_000000_create_some_table.php
- 2017_09_05_000001_add_field_x_to_some_table.php
- 2017_09_05_000002_add_field_y_to_some_table.php
- 2017_09_05_000003_add_field_z_to_some_table.php
हम एक और माइग्रेशन बनाएंगे:
- 2017_09_05_000004_pre_refresh.php
हमारे पास अभी जो ज्ञान है, उसके आधार पर हम एक और माइग्रेशन बनाएंगे:
- 2017_09_05_000005_create_some_table.php
हम अंतिम बुकएंड बनाएंगे, जहां डेटा माइग्रेशन होगा:
- 2017_09_05_000006_post_refresh.php
पहले चार माइग्रेशन नहीं चलाए जाएंगे क्योंकि वे पहले ही हो चुके हैं।
/** 2017_09_05_000004_pre_refresh.php */
class PreRefresh extends Migration
{
public function up()
{
$prefix = 'zz_';
$tablesToRename = [
'foos',
'bars'
];
foreach($tablesToRename as $table) {
Schema::rename($table, $prefix . $table);
}
}
}
डाउन की कोई आवश्यकता नहीं है, क्योंकि यह एक बार का सौदा है। यह पहले चलेगा, जिसके परिणामस्वरूप सरणी में सूचीबद्ध सभी तालिकाओं का नाम बदलना चाहिए। फिर समेकित (अनुकूलित) माइग्रेशन चलेंगे।
/** 2017_09_05_000006_post_refresh.php */
class PostRefresh extends Migration
{
public function up()
{
// Do what you need to do.
// If you cannot use your models, just use DB::table() commands.
$foos = DB::table('zz_foos')->get();
foreach ($foos as $foo) {
DB::table('foo')->insert([
'id' => $foo->id,
'created_at' => $foo->created_at,
'updated_at' => $foo->updated_at
]);
}
$bars = DB::table('zz_bars')->get();
foreach ($bars as $bar) {
DB::table('bar')->insert([
'id' => $bar->id,
'created_at' => $bar->created_at,
'updated_at' => $bar->updated_at,
'foo_id' => $bar->foo_id
]);
}
// Tear down.
$prefix = 'zz_';
$tablesToRename = [
'foo',
'bar'
];
foreach ($tablesToRename as $table) {
DB::statement('SET FOREIGN_KEY_CHECKS=0');
Schema::dropIfExists($prefix . $table);
DB::statement('SET FOREIGN_KEY_CHECKS=1');
}
}
}
इसे चलाने के बाद, आप pre_refresh
. से अपने सभी माइग्रेशन हटा सकते हैं और पूर्व। साथ ही post_refresh
. फिर आप migrations
. में जा सकते हैं तालिका बनाएं और उन माइग्रेशन के लिए प्रविष्टियां हटाएं।
प्रविष्टियों को हटाना पूरी तरह से आवश्यक नहीं है, लेकिन यदि आप migrate:rollback
करते हैं आपको यह बताते हुए त्रुटि संदेश प्राप्त होंगे कि माइग्रेशन नहीं मिला।
चेतावनी
- यदि आर्किटेक्चर डिजाइन द्वारा मॉड्यूलर नहीं है, तो यह काफी बोझिल हो सकता है। हालांकि, अगर आपने अपने कोड को सेवाओं में अलग कर दिया है तो यह थोड़ा आसान प्रतीत होता है।
- लारवेल त्रुटि प्रबंधन और माइग्रेशन के दौरान संदेश बहुत सीमित हैं; इसलिए, डिबगिंग मुश्किल हो सकती है।
- अपने ऐप/सेवा में सबसे स्थिर तालिकाओं के साथ शुरुआत करने की अत्यधिक अनुशंसा करते हैं। इसके अलावा, उन लोगों से शुरू करना जो आपके ऐप की नींव हैं, भी फायदेमंद साबित हो सकते हैं।
नोट:जब मैं वास्तव में इसे उत्पादन में करता हूं, न कि केवल मेरे स्थानीय (बार-बार), और यदि कोई बेहतर उत्तर नहीं है, तो मैं इसे स्वीकार करूंगा।
विचारों
यदि आप विवेकपूर्ण माइग्रेशन के साथ सेवा प्रदाताओं में अपना आवेदन तोड़ रहे हैं, तो आप सेवा प्रदाता को /config/app
में टिप्पणी कर सकते हैं जब आप माइग्रेशन चलाते हैं। इस तरह आप अब बेसलाइन सेवा के लिए एक बैच बनाते हैं। तो, मान लें कि आपके पास निम्न माइग्रेशन हैं जहां प्रत्येक अक्षर माइग्रेशन का प्रतिनिधित्व करता है, और प्रत्येक डुप्लिकेट अक्षर एक ही सेवा का प्रतिनिधित्व करता है:
- ए
- बी
- सी
- ए
- सी
- बी
- ए
सेवा ए को मजबूत करने के बाद:
- बी
- सी
- सी
- बी
- ए
बी को मजबूत करने के बाद:
- सी
- सी
- ए
- बी
C को समेकित करने के बाद:
- ए
- बी
- सी
अपडेट करें
अब तक 54 पलायन घटकर 27 रह गए हैं। मैंने बड़े up()
. से कुछ स्कीमा परिवर्तन भी निकाले और down()
तरीके और उन्हें अलग माइग्रेशन बनाते हैं। यहाँ अच्छा दुष्प्रभाव बैच है। मैं बेस टेबल से शुरू होकर माइग्रेट हुआ, जिस पर बाकी सब कुछ समर्थित है; इसलिए, रोल बैक करना सेवा द्वारा अधिक सेवा है।