22 अक्टू॰ 2025·8 मिनट पढ़ने में

पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास ताकि माइग्रेशन अनुमानित रहें

पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास यह सुनिश्चित करता है कि जब बैकएंड regenerate हो तो प्रोडक्शन डेटा वैध रह सके। स्कीमा बदलने और माइग्रेशन की योजना बनाने का व्यावहारिक तरीका सीखें।

पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास ताकि माइग्रेशन अनुमानित रहें

क्यों स्कीमा बदलाव regenerated बैकएंड के साथ जोखिम भरे लगते हैं

जब आपका बैकएंड एक विज़ुअल मॉडल से पुनर्जेनरेट होता है, तो एक डेटाबेस बदलाव स्वेटर की धाग खींचने जैसा लग सकता है। आप Data Designer में एक फ़ील्ड बदलते हैं, regenerate पर क्लिक करते हैं, और अचानक आप सिर्फ़ एक टेबल नहीं बदल रहे होते। आप जनरेटेड API, वैलिडेशन नियम, और आपके ऐप के पढ़ने/लिखने के क्वेरी भी बदल रहे होते हैं।

अक्सर जो गलत होता है वह यह नहीं कि नया कोड बिल्ड नहीं होता। कई नो‑कोड प्लेटफ़ॉर्म (AppMaster सहित, जो बैकएंड के लिए असली Go कोड जनरेट करता है) हर बार साफ़ प्रोजेक्ट जनरेट कर देंगे। असली जोखिम यह है कि प्रोडक्शन में पहले से मौजूद डेटा अपने आप आपके नए विचारों के अनुसार रूपांतरित नहीं होता।

लोग पहली बार जो दो विफलताएँ देखते हैं वे साधारण हैं:

  • टूटी हुई रीड्स: ऐप रिकॉर्ड लोड नहीं कर पाता क्योंकि कोई कॉलम हिला, टाइप बदला, या क्वेरी कुछ और उम्मीद कर रही है।
  • टूटी हुई राइट्स: नए या अपडेट किए गए रिकॉर्ड असफल होते हैं क्योंकि constraints, required फ़ील्ड या फॉर्मैट बदल गए हैं और पुराने क्लाइंट अब भी पुराना आकार भेज रहे हैं।

दोनों ही दर्दनाक हैं क्योंकि वे तब तक छुपे रह सकते हैं जब तक असली यूज़र्स मुद्दा न देखें। स्टेजिंग डेटाबेस खाली या ताज़ा सीडेड हो सकता है, इसलिए सब ठीक लगता है। प्रोडक्शन में किनारे के केस होते हैं: NULL जहां आपने वैल्यू मान ली, पुराने enum स्ट्रिंग्स, या पंक्तियाँ जो किसी नए नियम के बनने से पहले बनी थीं।

इसीलिए पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास मायने रखता है। लक्ष्य यह है कि हर बदलाव सुरक्षित हो—even जब बैकएंड पूरा regenerate हो जाए—ताकि पुराने रिकॉर्ड वैध रहें और नए रिकॉर्ड बनाए जा सकें।

“पूर्वानुमेय माइग्रेशन” का मतलब बस यह है कि आप डिप्लॉय करने से पहले चार सवालों का जवाब दे सकें: डेटाबेस में क्या बदलेगा, मौजूदा रिकॉर्ड्स के साथ क्या होगा, रोलआउट के दौरान किस ऐप वर्ज़न का काम चलता रहेगा, और यदि कुछ अनअपेक्षित दिखे तो आप कैसे रोलबैक करेंगे।

एक सरल मॉडल: स्कीमा, माइग्रेशन्स, और regenerate किया गया कोड

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

पुनर्जेनरेशन को “लेटेस्ट मॉडल से एप्लिकेशन कोड का फिर से बनाना” समझें। AppMaster जैसे टूल में यह rebuild अक्सर होता है: आप एक फ़ील्ड बदलते हैं, बिजनेस लॉजिक एडजस्ट करते हैं, एक एन्डपॉइंट जोड़ते हैं, regenerate करते हैं, टेस्ट करते हैं, और दोहराते हैं। पुनर्जेनरेशन अक्सर होता है। आपका प्रोडक्शन डेटाबेस ऐसा नहीं होना चाहिए।

यहाँ सरल मॉडल है:

  • स्कीमा: आपके डेटाबेस टेबल, कॉलम, इंडेक्स और constraints की संरचना। यह वही है जो डेटाबेस उम्मीद करता है।
  • माइग्रेशन्स: क्रमबद्ध, दोहराए जाने योग्य स्टेप्स जो स्कीमा को एक वर्ज़न से अगले वर्ज़न तक ले जाते हैं (और कभी-कभी डेटा भी बदलते हैं)। इन्हें हर वातावरण पर चलाया जाता है।
  • रनटाइम डेटा: यूज़र्स और प्रोसेसेस द्वारा बनाए गए असली रिकॉर्ड। उन्हें बदलाव से पहले, दौरान और बाद में वैध रहना चाहिए।

पुनर्जेनरेटेड कोड को “वर्तमान ऐप जो वर्तमान स्कीमा से बोलता है” की तरह ट्रीट करें। माइग्रेशन्स वह पुल हैं जो स्कीमा और रनटाइम डेटा को कोड के बदलने के साथ संरेखित रखते हैं।

क्यों पुनर्जेनरेशन गेम बदलता है

यदि आप बार‑बार regenerate करते हैं, तो स्वाभाविक रूप से आप कई छोटे स्कीमा संपादन करेंगे। यह सामान्य है। जोखिम तब आता है जब वे संपादन ऐसे डेटाबेस परिवर्तन का सुझाव देते हैं जो बैकवर्ड‑कम्पैटिबल नहीं हैं, या आपका माइग्रेशन निर्धारक (deterministic) नहीं है।

एक व्यावहारिक तरीका यह है कि आप पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास को छोटे, उलटने योग्य स्टेप्स की श्रृंखला के रूप में प्लान करें। एक बड़े स्विच की बजाय नियंत्रित चालें करें जो थोड़े समय के लिए पुराने और नए कोड रास्तों को साथ में काम करने दें।

उदाहरण के लिए, यदि आप किसी लाइव API द्वारा उपयोग किए जा रहे कॉलम का नाम बदलना चाहते हैं, तो उसे तुरंत rename न करें। पहले नया कॉलम जोड़ें, दोनों में लिखें, मौजूदा पंक्तियों को बैकफिल करें, फिर पढ़ने को नए कॉलम पर स्विच करें। उसके बाद ही पुराना कॉलम हटाएँ। हर कदम की आसानी से टेस्टिंग हो सकती है, और यदि कुछ गलत हुआ तो आप बिना डेटा खराब किए रोक सकते हैं।

यह मानसिक मॉडल माइग्रेशन्स को पूर्वानुमेय बनाता है, भले ही कोड regeneration रोज़ हो रहा हो।

स्कीमा बदलाव के प्रकार और कौन‑से प्रोडक्शन तोड़ते हैं

जब आपका बैकएंड लेटेस्ट स्कीमा से regenerate होता है, कोड आमतौर पर मानता है कि डेटाबेस अभी उसी स्कीमा से मेल खाता है। इसलिए पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास इस बारे में ज्यादा है: “क्या पुराना डेटा और पुराने अनुरोध बदलाव के रोलआउट के दौरान बच पाएंगे?”

कुछ बदलाव स्वाभाविक रूप से सुरक्षित होते हैं क्योंकि वे मौजूद पंक्तियों या क्वेरीज़ को अमान्य नहीं करते। अन्य बदलाव डेटा का अर्थ बदल देते हैं या कुछ हटाते हैं जो चल रही ऐप अभी भी उम्मीद करती है—यहीं प्रोडक्शन घटनाएँ होती हैं।

कम‑जोखिम, आमतौर पर सुरक्षित (एडिटिव)

एडिटिव बदलाव भेजना आसान होते हैं क्योंकि वे पुराने डेटा के साथ सह-अस्तित्व कर सकते हैं।

  • नया टेबल जिसे अभी कुछ निर्भर नहीं करता।
  • नया nullable कॉलम बिना किसी डिफ़ॉल्ट आवश्यकता के।
  • नया API फ़ील्ड जो एंड‑टू‑एंड वैकल्पिक हो।

उदाहरण: users तालिका में nullable middle_name कॉलम जोड़ना आमतौर पर सुरक्षित है। मौजूदा पंक्तियाँ वैध रहती हैं, regenerated कोड जब उपलब्ध होगा तब पढ़ सकेगा, और पुराने रिकॉर्ड में बस NULL रहेगा।

मध्यम‑जोखिम (अर्थ बदलते हैं)

ये बदलाव तकनीकी रूप से “काम कर सकते हैं” पर व्यवहार को तोड़ देते हैं। इन्हें सावधानी से समन्वय की ज़रूरत होती है क्योंकि regeneration validations, जनरेटेड मॉडल्स, और बिजनेस लॉजिक के अनुमान बदल देता है।

Renames क्लासिक जाल हैं: phone को mobile_phone में बदलने से regenerate हुआ कोड अब phone नहीं पढ़ेगा, जबकि प्रोडक्शन में डेटा वहीं मौजूद होगा। इसी तरह यूनिट बदलना (मूल्य डॉलर बनाम सेंट में स्टोर करना) गणनाओं को silently भ्रष्ट कर सकता है यदि आप कोड को पहले अपडेट कर दें या डेटा पहले बदल दें।

Enums भी नुकीले होते हैं। enum को कठोर करना (मान हटाना) मौजूदा पंक्तियों को अमान्य बना सकता है। enum बढ़ाना (मान जोड़ना) आमतौर पर सुरक्षित है, पर तब तक ही जब तक सभी कोड पाथ नए मान को संभाल सकें।

व्यावहारिक तरीका यह है कि अर्थ बदलने वाले बदलावों को “नया जोड़ो, बैकफिल करो, स्विच करो, फिर बाद में हटाओ” की तरह समझें।

उच्च‑जोखिम (विनाशकारी)

विनाशकारी बदलाव वे होते हैं जो प्रायः तुरंत प्रोडक्शन तोड़ देते हैं, विशेषकर जब प्लेटफ़ॉर्म ऐसा कोड regenerate करता है जो पुराने आकार की उम्मीद बंद कर दे।

कॉलम ड्रॉप करना, टेबल ड्रॉप करना, या nullable से not‑null में बदलना वह क्षण है जब कोई भी अनुरोध उस वैल्यू के बिना इन्सर्ट करने की कोशिश करेगा तो फेल हो सकता है। भले ही आप सोचें “सभी पंक्तियाँ पहले से मौजूद हैं,” अगला किनारा‑केस या बैकग्राउंड जॉब इसका विरोध कर सकता है।

यदि आपको not‑null बदलाव करना ही है तो चरणों में करें: पहले कॉलम nullable के रूप में जोड़ें, बैकफिल करें, ऐप लॉजिक अपडेट करें ताकि यह हमेशा वैल्यू सेट करे, फिर not‑null लागू करें।

प्रदर्शन और सुरक्षा बदलाव (लेखनों को रोक सकते हैं)

इंडेक्स और constraints “डेटा आकार” के बदलाव नहीं हैं, पर वे फिर भी downtime या लेखन रोकने का कारण बन सकते हैं। बड़ी तालिका पर इंडेक्स बनाना या यूनिक constraint जोड़ना लिखावट को लॉक कर सकता है और टाइमआउट करवा सकता है। PostgreSQL में कुछ ऑपरेशन्स ऑनलाइन‑फ्रेंडली तरीकों से सुरक्षित होते हैं, पर मुख्य बिंदु समय है: भारी ऑपरेशन्स कम ट्रैफ़िक के दौरान करें और स्टेजिंग कॉपी में उनकी अवधि मापें।

जब बदलाव प्रोडक्शन में अतिरिक्त सावधानी मांगते हैं, तो योजना बनाएं:

  • दो‑स्टेप रोलआउट (पहले स्कीमा, फिर कोड, या विपरीत) जो कम्पैटिबिलिटी बनाये रखे।
  • बैकफिल्स जो बैचों में चले।
  • स्पष्ट रोलबैक पाथ (अगर regenerate किया बैकएंड जल्दी लाइव हो जाए तो क्या होगा)।
  • सत्यापन क्वेरीज़ जो साबित करें कि डेटा नए नियमों से मेल खाता है।
  • "पुराने फ़ील्ड को बाद में हटाने" का टिकट ताकि क्लीनअप उसी डिप्लॉय में न हो।

यदि आप AppMaster जैसे प्लेटफ़ॉर्म का उपयोग कर रहे हैं जो Data Designer से बैकएंड को regenerate करता है, तो सबसे सुरक्षित मानसिकता यह है: ऐसे बदलाव भेजें जिनके साथ पुराना डेटा आज भी जी सके, और सिस्टम के अनुकूल हो जाने के बाद नियम कड़े करें।

पुनर्जेनरेशन‑सुरक्षित बदलावों के सिद्धांत

Regenerated बैकएंड तब अच्छे होते हैं जब तक कोई स्कीमा बदलाव प्रोडक्शन में न उतरता और पुराने रिकॉर्ड नए आकार से न मिलते। पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास का लक्ष्य सरल है: आपका ऐप तब तक काम करता रहे जब तक डेटाबेस और पुनर्जेनरेटेड कोड छोटे, पूर्वानुमेय स्टेप्स में एक‑दूसरे के साथ समायोजित हो रहे हों।

डिफ़ॉल्ट तौर पर “विस्तार, माइग्रेट, संकुचन” अपनाएँ

हर मायने रखता बदलाव को तीन चालों के रूप में देखें। पहले स्कीमा का विस्तार करें ताकि पुराने और नए कोड दोनों चल सकें। फिर डेटा माइग्रेट करें। और अंत में पुराने कॉलम, डिफ़ॉल्ट, या constraints हटाकर संकुचन करें।

व्यावहारिक नियम: "नए स्ट्रक्चर" और "ब्रेकेिंग क्लीनअप" को एक ही डिप्लॉय में कभी न मिलाएँ।

कुछ समय के लिए पुराने और नए आकार का समर्थन करें

मान लीजिए ऐसे समय होंगे जब:

  • कुछ रिकॉर्ड्स में नए फ़ील्ड होंगे, कुछ में नहीं
  • कुछ ऐप इंस्टेंसेज़ पुराने कोड पर चल रहे होंगे, कुछ regenerate किए गए कोड पर
  • बैकग्राउंड जॉब्स, इम्पोर्ट्स, या मोबाइल क्लाइंट पीछे रह सकते हैं

डिज़ाइन ऐसा रखें कि ओवरलैप के दौरान दोनों आकार वैध हों। यह और भी महत्वपूर्ण है जब प्लेटफ़ॉर्म आपके बैकएंड को लेटेस्ट मॉडल से regenerate करे (उदाहरण के लिए AppMaster में जब आप Data Designer अपडेट करते हैं और Go बैकएंड regenerate करते हैं)।

राइट करने से पहले पढ़ने को कम्पैटिबल बनाएं

सबसे पहले नया कोड पुराने डेटा को सुरक्षित रूप से पढ़ पाए—यही शुरूआत होनी चाहिए। फिर ही लिखने के पाथ को नए डेटा आकार की तरफ स्विच करें।

उदाहरण: यदि आप status फ़ील्ड को status + status_reason में बाँट रहे हैं, तो पहले ऐसा कोड भेजें जो गायब status_reason को संभाल सके। उसके बाद ही status_reason लिखना शुरू करें।

आंशिक और अज्ञात डेटा के साथ क्या करें तय करें

जब आप एनम्स, नॉन‑नल कॉलम, या कड़े constraints जोड़ते हैं, पहले तय कर लें कि जब वैल्यू गायब या अनपेक्षित हो तो क्या होना चाहिए:

  • अस्थायी रूप से NULL की अनुमति दें, फिर बैकफिल करें
  • ऐसा सुरक्षित डिफ़ॉल्ट सेट करें जो अर्थ न बदले
  • "unknown" वैल्यू रखें ताकि रीड्स फेल न हों

इससे साइलेंट करप्शन (गलत डिफ़ॉल्ट्स) और हार्ड फेल्योर (नए constraints द्वारा पुराने रिकॉर्ड का अस्वीकार) से बचाव होगा।

हर स्टेप के लिए रोलबैक कहानी रखें

विस्तार चरण के दौरान रोलबैक सबसे आसान होता है। यदि आपको revert करना पड़े, तो पुराना कोड विस्तारित स्कीमा के खिलाफ चलना चाहिए। लिखें कि आप क्या रोलबैक करेंगे (सिर्फ़ कोड, या कोड के साथ माइग्रेशन), और तब तक विनाशकारी बदलाव से बचें जब तक आप निश्चित न हों कि आपको undo नहीं करना पड़ेगा।

चरण दर चरण: ऐसा बदलाव प्लान करें जो पुनर्जेनरेशन में बचे

विस्तार → माइग्रेट → संकुचन अपनाएँ
नए फ़ील्ड जोड़ें, डेटा बैकफिल करें, और पढ़ने को सुरक्षित रूप से स्विच करें — स्पष्ट रोलआउट स्टेप्स के साथ।
अब बनाएं

Regenerated बैकएंड unforgiving होते हैं: यदि स्कीमा और जनरेटेड कोड असमान हों, तो आमतौर पर प्रोडक्शन पहले पकड़ेगा। सबसे सुरक्षित तरीका यह है कि हर बदलाव को छोटे, उलटने योग्य रोलआउट की तरह ट्रीट किया जाए, भले ही आप नो‑कोड टूल से बना रहे हों।

पहले अपने इरादे को साधारण भाषा में और आज आपके डेटा का रूप लिख कर रखें। प्रोडक्शन से 3–5 असली रिकॉर्ड्स चुनें (या हाल की डंप) और गंदे हिस्सों को नोट करें: खाली वैल्यूज़, पुराने फॉर्मैट, चौंकाने वाले डिफ़ॉल्ट्स। इससे आप ऐसे नए फ़ील्ड डिजाइन करने से बचेंगे जिन्हें असली डेटा पूरा नहीं कर सके।

यहां एक व्यावहारिक क्रम है जो प्लेटफ़ॉर्म के regenerate करने पर अच्छी तरह काम करता है (उदा., AppMaster जब Data Designer से Go बैकएंड सर्विसेज regenerate करता है):

  1. पहले विस्तार करें, प्रतिस्थापित मत करें। नए कॉलम या टेबलेस ऐड करें एडिटिव तरीके से। नए फ़ील्ड पहले nullable रखें, या सुरक्षित डिफ़ॉल्ट दें। यदि नया संबंध जोड़ रहे हैं, तो foreign key को तब तक खाली रहने दें जब तक आप उसे भर न लें।

  2. कुछ भी हटाए बिना विस्तारित स्कीमा डिप्लॉय करें। डेटाबेस परिवर्तन भेजें जब पुराना कोड अभी भी चले। लक्ष्य: पुराना कोड पुराने कॉलम लिखना जारी रख सके और डेटाबेस उसे स्वीकार करे।

  3. नियंत्रित जॉब में बैकफिल करें। नए फ़ील्ड्स को बैच प्रोसेस से भरें जिसे आप मॉनिटर और दोबारा चला सकें। इसे idempotent रखें (दो बार चलाने से डेटा भ्रष्ट न हो)। बड़ी तालिका हो तो धीरे‑धीरे करें और लॉग रखें कि कितनी पंक्तियाँ अपडेट हुईं।

  4. पहले पढ़ने को स्विच करें, fallback के साथ। regenerated लॉजिक को अपडेट करें ताकि वह नए फ़ील्ड को प्राथमिकता दे पर नया डेटा गायब होने पर पुराने पर fallback करे। पढ़ने स्थिर होने के बाद ही लिखने को नए फ़ील्ड्स पर शिफ्ट करें।

  5. आख़िर में साफ़ करें। भरोसा होने पर (और रोलबैक प्लान के साथ), पुराने फ़ील्ड हटाएँ और constraints कड़े करें: NOT NULL सेट करें, यूनिक constraints जोड़ें, और foreign keys लागू करें।

ठोस उदाहरण: आप free‑text status कॉलम को statuses तालिका की ओर इशारा करने वाले status_id से बदलना चाहते हैं। पहले status_id को nullable के रूप में जोड़ें, मौजूद टेक्स्ट से बैकफिल करें, ऐप को अपडेट करें ताकि वह status_id पढ़े पर null होने पर status पर fallback करे, फिर अंत में status हटाएँ और status_id required बनाएं। इस प्रकार हर चरण में डेटाबेस हमेशा कम्पैटिबल रहता है और पुनर्जेनरेशन सुरक्षित बनती है।

साझा किए जाने योग्य व्यावहारिक पैटर्न

इन्टरनल ऐप तेज़ी से लॉन्च करें
आंतरिक टूल और एडमिन पैनल लॉन्च करें जो स्कीमा बदलते समय स्थिर रहें।
पोर्टल बनाएं

जब आपका बैकएंड regenerate होता है, छोटे‑छोटे स्कीमा बदलाव APIs, validations, और UI फॉर्म्स में प्रभाव डाल सकते हैं। उद्देश्य यह है कि बदलाव ऐसे हों कि पुराना डेटा वैध रहे जबकि नया कोड रोल आउट हो रहा हो।

पैटर्न 1: गैर‑टूटने वाला रीनाम

डायरेक्ट rename जोखिमभरा है क्योंकि पुराने रिकॉर्ड और पुराने कोड अक्सर मूल फ़ील्ड की उम्मीद करते हैं। सुरक्षित तरीका यह है कि rename को छोटे माइग्रेशन पीरियड की तरह ट्रीट करें:

  • नया कॉलम जोड़ें (customer_phone) और पुराना रखें (phone).
  • लॉजिक को dual‑write करें: सेव करते समय दोनों में लिखें।
  • मौजूदा पंक्तियों को बैकफिल करें ताकि customer_phone भर जाए।
  • कवरेज हाई होने पर पढ़ना नए कॉलम पर स्विच करें।
  • बाद की रिलीज़ में पुराना कॉलम ड्रॉप करें।

यह AppMaster जैसे टूल्स में अच्छी तरह काम करता है जहाँ regeneration लेटेस्ट स्कीमा से डेटा मॉडल और एन्डपॉइंट्स को rebuild कर देगा। Dual‑write दोनों जेनरेशन्स के कोड को संक्रमण के दौरान खुश रखता है।

पैटर्न 2: एक फ़ील्ड को दो में बाँटना

full_name को first_name और last_name में बाँटना समान है, पर बैकफिल कठिन है। full_name तब तक रखें जब तक आप सुनिश्चित न हों कि विभाजन पूरा हो गया है।

व्यावहारिक नियम: मूल फ़ील्ड तब तक न हटाएँ जब तक हर रिकॉर्ड बैकफिल न हो या स्पष्ट fallback न हो। यदि पार्सिंग फेल हो, तो पूरी स्ट्रिंग last_name में रखें और रिकॉर्ड को समीक्षा के लिए फ़्लैग करें।

पैटर्न 3: फ़ील्ड को आवश्यक बनाना

nullable से required करना क्लासिक प्रोडक्शन ब्रेकर है। सुरक्षित क्रम: पहले बैकफिल करें, फिर लागू करें।

बैकफिल मैकेनिकल हो सकता है (सुरक्षित डिफ़ॉल्ट सेट करें) या बिजनेस‑ड्रिवन (यूज़र्स से गायब डेटा भरवाएँ)। डेटा पूरा होने के बाद ही NOT NULL और वैलिडेशन लागू करें। यदि आपका regenerated बैकएंड स्वचालित रूप से सख्त वैलिडेशन जोड़ता है, तो यह क्रम आश्चर्यजनक फेल्योर से बचाता है।

पैटर्न 4: एनम को सुरक्षित बदलना

एनम तब टूटता है जब पुराना कोड पुराने मान भेजे। संक्रमण के दौरान दोनों को स्वीकार करें। यदि आप "pending" को "queued" से बदल रहे हैं, तो दोनों मान वैध रखें और लॉजिक में मैप करें। जब आप पुष्टि कर लें कि कोई क्लाइंट पुराना मान नहीं भेजता, तब उसे हटा दें।

यदि बदलाव एक रिलीज़ में ही जाना अनिवार्य है, तो जोखिम घटाने के लिए ब्लास्ट रेडियस को संकुचित करें:

  • नए फ़ील्ड जोड़ें पर पुराने रखें, भले ही वे अनुपयोगी हों।
  • डेटाबेस डिफ़ॉल्ट रखें ताकि इनसर्ट्स काम करते रहें।
  • कोड को सहिष्णु बनाएं: नए से पढ़ें, पुराने पर fallback करें।
  • अस्थायी मैपिंग लेयर जोड़ें (पुराना इन — नया स्टोर)।

ये पैटर्न माइग्रेशन्स को पूर्वानुमेय बनाते हैं भले ही regenerated कोड व्यवहार जल्दी बदल रहा हो।

सामान्य गलतियाँ जो आश्चर्य पैदा करती हैं

सबसे बड़े आश्चर्य तब आते हैं जब लोग कोड regeneration को जादुई रीसेट बटन समझ लेते हैं। Regenerated बैकएंड आपके एप्लिकेशन को साफ़ रख सकता है, पर आपका प्रोडक्शन डेटाबेस फिर भी कल का डेटा रखता है, कल के आकार के साथ। पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास का मतलब यह है कि आप दोनों की योजना बनाएं: नया कोड जो जनरेट होगा और पुराने रिकॉर्ड जो अभी भी तालिकाओं में बैठे हैं।

एक सामान्य फंसाव यह मानना है कि प्लेटफ़ॉर्म "माइग्रेशन्स संभाल लेगा।" उदाहरण के लिए AppMaster में आप अपने Data Designer मॉडल से Go बैकएंड regenerate कर सकते हैं, पर प्लेटफ़ॉर्म यह अनभिज्ञ है कि आप असली ग्राहक डेटा को कैसे बदलना चाहते हैं। यदि आप नया required फ़ील्ड जोड़ते हैं, तो भी आपको यह स्पष्ट योजना बनानी होगी कि मौजूदा रिकॉर्ड्स में वैल्यू कैसे आएगी।

एक और आश्चर्य यह है कि फ़ील्ड्स को जल्दबाज़ी में ड्रॉप या रीनेम कर देना। एक फ़ील्ड मुख्य UI में अनयूज़्ड लग सकती है, पर फिर भी रिपोर्ट, शेड्यूलड एक्सपोर्ट, वेबहुक हैंडलर, या कभी‑कभार खोले जाने वाले एडमिन स्क्रीन द्वारा पढ़ी जा सकती है। टेस्टिंग में यह सुरक्षित दिखता है, फिर प्रोडक्शन में कोई भूला हुआ कोड पाथ असफल कर देता है।

यहाँ पाँच गलतियाँ जो देर रात के रोलबैक का कारण बनती हैं:

  • स्कीमा बदलना और कोड regenerate करना, पर वह डेटा माइग्रेशन न लिखना/सत्यापित करना जो पुराने रिकॉर्ड्स को वैध बनाए।
  • हर रीडर और राइटर अपडेट और डिप्लॉय किए बिना कॉलम का नाम बदलना या हटाना।
  • बड़ी तालिका का बैकफिल बिना यह देखे चलाना कि वह कितना समय लेगा और क्या यह अन्य लिखावट को ब्लॉक करेगा।
  • पहले नया constraint (NOT NULL, UNIQUE, foreign key) जोड़ना और फिर पाना कि लेगेसी डेटा उसे तोड़ता है।
  • बैकग्राउंड जॉब्स, एक्सपोर्ट्स और रिपोर्ट्स को भूल जाना जो अभी भी पुराने फ़ील्ड पढ़ते हैं।

सरल परिदृश्य: आपने phone को mobile_number में rename किया, NOT NULL constraint जोड़ दिया, और regenerate कर दिया। ऐप स्क्रीन काम कर सकती हैं, पर एक पुराना CSV एक्सपोर्ट अभी भी phone चुनता है, और हजारों रिकॉर्ड में mobile_number NULL है। इलाज आमतौर पर चरणबद्ध बदलाव होता है: नया कॉलम जोड़ें, दोनों में लिखें थोड़ी देर, सुरक्षित बैकफिल करें, फिर constraints कड़े करें और पुराना फ़ील्ड तब हटाएँ जब आपको प्रमाण मिले कि कुछ भी उस पर निर्भर नहीं करता।

सुरक्षित माइग्रेशन्स के लिए त्वरित प्री‑डिप्लॉय चेकलिस्ट

पहले अपना स्कीमा विज़ुअलाइज़ करें
प्रोडक्शन को छूने से पहले Data Designer में टेबल और रिलेशन डिज़ाइन करें।
इसे आज़माएँ

जब आपका बैकएंड regenerate होता है, तो कोड जल्दी बदल सकता है, पर आपका प्रोडक्शन डेटा आश्चर्य बर्दाश्त नहीं करेगा। किसी भी स्कीमा बदलाव को भेजने से पहले एक छोटा “क्या यह सुरक्षित तरीके से फेल कर सकता है?” चेक चलाएँ। यह पुनर्जेनरेशन‑सुरक्षित स्कीमा विकास को नीरस रखता है (और यही चाहिए)।

वे 5 चेक जो ज़्यादातर समस्याओं को पकड़ लेते हैं

  • बैकफिल आकार और गति: अनुमान लगाएँ कि कितनी मौजूदा पंक्तियों को अपडेट/री‑राइट करने की जरूरत है और प्रोडक्शन में यह कितना समय लेगा। छोटे DB पर ठीक बैकफिल असली डेटा पर घंटों ले सकता है और ऐप को धीमा कर सकता है।
  • लॉक्स और डाउनटाइम का जोखिम: पहचानें कि क्या यह बदलाव लिखावट को ब्लॉक कर सकता है। कुछ ऑपरेशन्स (जैसे बड़े टेबल्स पर alter या टाइप बदलना) लंबे लॉक रख सकते हैं। यदि किसी भी तरह का ब्लॉकिंग हो सकता है, तो सुरक्षित रोलआउट योजना बनाएं (पहले नया कॉलम जोड़ें, बाद में बैकफिल करें, अंतिम में कोड स्विच करें)।
  • पुराना कोड बनाम नया स्कीमा कम्पैटिबिलिटी: मान लीजिए कि पुराना बैकएंड थोड़ी देर के लिए नए स्कीमा के खिलाफ रन कर सकता है। सवाल पूछें: क्या पिछला वर्ज़न बिना क्रैश किए पढ़ और लिख पाएगा? यदि नहीं, तो आपको दो‑स्टेप रिलीज चाहिए।
  • डिफ़ॉल्ट और नल व्यवहार: नए कॉलम्स के लिए तय करें कि मौजूदा रिकॉर्ड्स के साथ क्या होगा। क्या वे NULL होंगे, या क्या आपको डिफ़ॉल्ट चाहिए? अपने लॉजिक को सुनिश्चित करें कि वह मिसिंग वैल्यूज़ को सामान्य मान के रूप में ट्रीट करे, खासकर फ्लैग्स, स्टेटस फ़ील्ड्स, और टाइमस्टैम्प्स में।
  • मॉनिटरिंग संकेत जिन पर नज़र रखनी है: उन अलार्म्स को चुनें जिन्हें आप डिप्लॉय के बाद घूरकर देखेंगे: एरर रेट (API फेल्योर), डेटाबेस स्लो क्वेरीज़, क्यू/जॉब फेल्योर, और कोई कíी यूज़र एक्शन (चेकआउट, लॉगइन, फॉर्म सबमिशन)। साथ ही “साइलेंट” बग्स जैसे वैलिडेशन एरर्स में स्पाइक पर भी नज़र रखें।

एक त्वरित उदाहरण

यदि आप orders तालिका में नया ज़रूरी फ़ील्ड status जोड़ रहे हैं, तो उसे एक ही बार में "NOT NULL, बिना डिफ़ॉल्ट" के रूप में पब्लिश मत करें। पहले उसे nullable के रूप में जोड़ें और नए रिकार्ड के लिए सुरक्षित डिफ़ॉल्ट रखें, regenerated कोड भेजें जो गायब status संभाले, फिर पुराने रिकॉर्ड्स को बैकफिल करें, और बाद में constraints कड़ाई से लागू करें।

AppMaster में यह मानसिकता विशेष रूप से उपयोगी है क्योंकि बैकएंड अक्सर regenerate हो सकता है। हर स्कीमा बदलाव को एक छोटे रिलीज की तरह ट्रीट करें जिसमें आसान रोलबैक हो, और आपकी माइग्रेशन्स पूर्वानुमेय रहेंगी।

उदाहरण: लाइव ऐप को विकसित करना बिना पुराने रिकॉर्ड्स तोड़े

एक मॉडल — वेब और मोबाइल दोनों के लिए
एक ही बैकएंड और स्कीमा के ऊपर वेब और नेटिव मोबाइल दोनों बनाएं।
प्रोजेक्ट शुरू करें

कठिन परिदृश्य सोचें: एक आंतरिक सपोर्ट टूल जहाँ एजेंट टिकट्स को free text फ़ील्ड priority से टैग करते हैं (जैसे: "high", "urgent", "HIGH", "p1"). आप रिपोर्ट्स और रूटिंग नियमों को सटीक बनाना चाहते हैं और कड़ा enum इस्तेमाल करना चाहते हैं।

सुरक्षित तरीका दो‑रिलीज़ परिवर्तन है जो पुराने रिकॉर्ड्स को वैध रखता है जबकि आपका बैकएंड regenerate हो रहा है।

रिलीज 1: विस्तार, दोनों में लिखें, और बैकफिल करें

शुरू में स्कीमा बिना कुछ हटाए विस्तारित करें। नया enum फ़ील्ड जोड़ें, जैसे priority_enum जिनमें low, medium, high, urgent मान हों। मूल priority_text फ़ील्ड रखें।

फिर लॉजिक अपडेट करें ताकि नए और एडिट किए गए टिकट दोनों फ़ील्ड में लिखें। नो‑कोड टूल में यह आमतौर पर Data Designer मॉडल और बिजनेस प्रोसेस को एडजस्ट करना होगा ताकि इनपुट को enum में मैप किया जाए और मौलिक टेक्स्ट भी स्टोर हो।

अगला, मौजूदा टिकट्स को छोटे बैचों में बैकफिल करें। सामान्य टेक्स्ट मानों को enum से मैप करें ("p1" और "urgent" → urgent, "HIGH" → high). अनजान मानों को अस्थायी रूप से medium पर मैप करें और समीक्षा के लिए फ़्लैग करें।

यूज़र्स को दिखने में आमतौर पर कोई बदलाव नहीं होता। UI वही priority कंट्रोल दिखा सकती है, पर अंदर नया enum भरना शुरू हो जाएगा। बैकफिल शुरु होने पर रिपोर्ट्स enum का उपयोग करना शुरू कर सकती हैं।

रिलीज 2: संकुचन और पुरानी पथ हटाना

जब आप आश्वस्त हों, पढ़ना केवल priority_enum पर स्विच करें, फ़िल्टर और डैशबोर्ड अपडेट करें, और बाद में priority_text को मिटा दें।

रिलीज 2 से पहले छोटे सैंपल से सत्यापन करें:

  • 20–50 टिकट्स चुनें विभिन्न टीमों और आयु समूहों से।
  • दिख रहे प्रायरिटी की तुलना स्टोर किए गए enum मान से करें।
  • enum मानों के अनुसार काउंट्स में असामान्य स्पाइक की जांच करें (उदा., बहुत सारे medium).

यदि मुद्दे आएँ, तो रोलबैक सरल है क्योंकि रिलीज 1 ने पुराना फ़ील्ड रखा: रिलीज 1 लॉजिक को फिर से deploy करें और UI को priority_text पढ़ने पर सेट करें जबकि आप मैपिंग को ठीक करें और बैकफिल फिर से चलाएँ।

अगला कदम: स्कीमा विकास को एक दोहराने योग्य आदत बनाएं

यदि आप पूर्वानुमेय माइग्रेशन्स चाहते हैं, तो स्कीमा बदलावों को एक छोटे प्रोजेक्ट की तरह ट्रीट करें, न कि एक त्वरित संपादन। लक्ष्य सरल है: हर बदलाव को समझाना आसान हो, रिहर्स करना आसान हो, और गलती से तोड़ना मुश्किल हो।

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

जब आपको किसी उपयोग किए जा चुके फ़ील्ड को बदलना हो, तो एका छोटे संक्रमणकाल को प्राथमिकता दें जिसमें फ़ील्ड्स डुप्लिकेट हों। उदाहरण के लिए, phone_e164 जोड़ें और phone_raw को एक या दो रिलीज़ तक रखें। बिजनेस लॉजिक को डिज़ाइन करें कि वह नए फ़ील्ड से पढ़े जब उपलब्ध हो और पुराने फ़ील्ड पर fallback करे जब नया न हो। संक्रमण के दौरान दोनों में लिखें, फिर केवल तब पुराना हटाएँ जब आपने डेटा पूरे तरह से बैकफिल कर लिया हो।

पर्यावरण अनुशासन अच्छी नियत को सुरक्षित रिलीज़ में बदलता है। dev, staging, और production को संरेखित रखें, पर उन्हें एक समान मत समझें।

  • Dev: यह साबित करें कि regenerated बैकएंड साफ़ तरीके से स्टार्ट होता है और बेसिक फ्लोज़ काम करते हैं।
  • Staging: प्रोडक्शन‑जैसे डेटा पर पूरा माइग्रेशन प्लान चलाएँ और मुख्य क्वेरीज, रिपोर्ट्स, और इम्पोर्ट्स को सत्यापित करें।
  • Production: तब डिप्लॉय करें जब आपके पास रोलबैक प्लान, स्पष्ट मॉनिटरिंग, और कुछ "पास होना जरूरी" चेक्स हों।

अपनी माइग्रेशन योजना को एक असली दस्तावेज़ बनाएं, भले ही यह छोटा हो। इसमें शामिल करें: क्या बदलेगा, क्रम क्या होगा, बैकफिल कैसे होगा, सत्यापन कैसे करेंगे, और रोलबैक कैसे होगा। फिर इसे टेस्‍ट वातावरण में एंड‑टू‑एंड चलाएँ उससे पहले कि यह प्रोडक्शन को छुए।

यदि आप AppMaster का उपयोग कर रहे हैं, तो Data Designer पर भरोसा करें ताकि आप विज़ुअली मॉडल का विश्लेषण कर सकें, और regeneration से अपने बैकएंड को अपडेटेड स्कीमा के साथ सुसंगत रखें। जो आदत चीज़ों को पूर्वानुमेय रखती है वह है: माइग्रेशन्स को स्पष्ट रखना—आप तेजी से इटरेट कर सकते हैं, पर हर बदलाव अभी भी मौजूद प्रोडक्शन डेटा के लिए एक तय‑शुदा रास्ता रखता हो।

शुरू करना आसान
कुछ बनाएं अद्भुत

फ्री प्लान के साथ ऐपमास्टर के साथ प्रयोग करें।
जब आप तैयार होंगे तब आप उचित सदस्यता चुन सकते हैं।

शुरू हो जाओ