नमस्ते! आज मैंने ThinkingHome.Migrator का एक नया संस्करण जारी किया - एक डेटाबेस स्कीमा के संस्करणित प्रवास के लिए एक टूल। .NET कोर प्लेटफॉर्म।

NuGet में प्रकाशित पैकेज, विस्तृत प्रलेखन लिखित। आप पहले से ही नए माइग्रेटर का उपयोग कर सकते हैं, और मैं आपको बताऊंगा कि यह कैसे दिखाई दिया, क्यों इसका संस्करण संख्या 3.0.0 है (हालांकि यह पहली रिलीज़ है) और ईएफ माइग्रेशन और फ़्लुएंटमिग्रेटर होने पर इसकी आवश्यकता क्यों है।
यह सब कैसे शुरू हुआ
9 साल पहले, 2009 में, मैंने ASP.NET डेवलपर के रूप में काम किया था। जब हमने अपनी परियोजना को जारी किया, तो एक विशेष व्यक्ति देर से रुका और साथ ही, सर्वर पर फ़ाइलों को अपडेट करने के साथ, अपने हाथों से एसक्यूएल स्क्रिप्ट को निष्पादित करता था, जो कि ठेस में डेटाबेस को अपडेट करता था। हमने एक ऐसा टूल खोजा है जो यह स्वचालित रूप से करेगा और माइग्रेटर.नेट प्रोजेक्ट को मिला।
माइग्रेटर ने उस समय के लिए एक नया विचार प्रस्तावित किया - माइग्रेशन के रूप में डेटाबेस परिवर्तन निर्धारित करने के लिए। प्रत्येक माइग्रेशन में परिवर्तनों का एक छोटा हिस्सा होता है और इसमें एक संस्करण संख्या होती है जिसमें डेटाबेस पूरा होने के बाद जाएगा। प्रवासी ने स्वयं संस्करणों का ट्रैक रखा और आवश्यक क्रम में आवश्यक पलायन किया। विशेष रूप से शांत तथ्य यह था कि प्रवासी ने प्रत्येक प्रवास के लिए रिवर्स परिवर्तन निर्धारित करने की अनुमति दी थी। प्रवासी की शुरुआत में वर्तमान संस्करण की तुलना में कम संस्करण को सेट करना संभव था, और यह रिवर्स संस्करण में आवश्यक माइग्रेशन का प्रदर्शन करते हुए, स्वचालित रूप से डेटाबेस को इस संस्करण में वापस कर देगा।
[Migration(1)] public class AddAddressTable : Migration { override public void Up() { Database.AddTable("Address", new Column("id", DbType.Int32, ColumnProperty.PrimaryKey), new Column("street", DbType.String, 50), new Column("city", DbType.String, 50) ); } override public void Down() { Database.RemoveTable("Address"); } }
उस प्रवासी में बहुत सारी गलतियाँ थीं। वह डिफ़ॉल्ट स्कीमा के अलावा डेटाबेस स्कीमा के साथ काम करना नहीं जानता था। कुछ मामलों में, यह गलत SQL क्वेरी उत्पन्न करता है, और यदि आप कोई भी संस्करण संस्करण निर्दिष्ट नहीं करते हैं, तो यह एक अनंत लूप में आता है। नतीजतन, मैंने और मेरे सहयोगियों ने परियोजना को ठीक कर दिया और वहाँ कीड़े लगा दिए।
उसके कांटे और पुल अनुरोध के साथ GitHub.com तब ( प्रवासी कोड code.google.com पर था) नहीं था। इसलिए, हमने विशेष रूप से यह सुनिश्चित करने की जहमत नहीं उठाई कि हमारे बदलाव मूल परियोजना में वापस आ गए - हमने सिर्फ अपनी प्रति देखी और खुद इसका इस्तेमाल किया। समय के साथ, हमने अधिकांश परियोजना को फिर से लिखा, और मैं इसका मुख्य अनुचर बन गया। फिर मैंने हमारे प्रवासी का कोड Google कोड पर पोस्ट किया और हैबर पर एक लेख लिखा। तो वहां ECM7.igrator था।
प्रवासी पर काम के दौरान, हमने इसे लगभग पूरी तरह से रद्द कर दिया। इसी समय, उन्होंने एपीआई को थोड़ा सरल किया और स्वचालित परीक्षणों के साथ सब कुछ कवर किया। व्यक्तिगत रूप से, मुझे वास्तव में जो हुआ उसका उपयोग करके बहुत अच्छा लगा। मूल प्रवासी के विपरीत, विश्वसनीयता की भावना थी और ऐसा कोई एहसास नहीं था कि अजीब जादू हो रहा था।
जैसा कि यह निकला, न केवल मुझे हमारा प्रवासी पसंद आया। जहां तक मुझे पता है, इसका इस्तेमाल काफी बड़ी कंपनियों में किया गया था। मैं ABBYY, BARS ग्रुप और कॉन्सर्ट.ru के बारे में जानता हूं। यदि आप खोज क्वेरी "ecm7 प्रवासी" में लिखते हैं, तो आप इसके बारे में परिणाम लेखों में देख सकते हैं, फिर से शुरू में उल्लेख, छात्र के काम में उपयोग के विवरण। कभी-कभी मुझे अजनबियों से प्रश्न या आभार शब्द के साथ पत्र मिलते थे।
2012 के बाद, परियोजना लगभग विकसित नहीं हुई। इसकी वर्तमान क्षमताओं ने उन सभी कार्यों को कवर किया जो मेरे पास थे और मुझे कुछ खत्म करने की आवश्यकता नहीं थी।
ThinkingHome.Migrator
पिछले साल, मैंने .NET कोर पर एक प्रोजेक्ट पर काम करना शुरू किया। वहां प्लगइन्स को कनेक्ट करना संभव बनाने के लिए आवश्यक था, और प्लगइन्स को अपने डेटा को स्टोर करने के लिए अपने लिए आवश्यक डेटाबेस संरचना बनाने में सक्षम होना चाहिए। यह केवल एक ऐसा कार्य है, जिसके लिए एक प्रवासी अच्छी तरह से अनुकूल है।
Ef माइग्रेशन
मैंने डेटाबेस के साथ काम करने के लिए एंटिटी फ्रेमवर्क कोर का उपयोग किया, इसलिए मैंने जो पहली कोशिश की वह ईएफ माइग्रेशन थी। दुर्भाग्य से, लगभग तुरंत मुझे उन्हें उपयोग करने का विचार त्यागना पड़ा।
एंटिटी फ्रेमवर्क माइग्रेशन प्रोजेक्ट में निर्भरता का एक गुच्छा खींचते हैं, और स्टार्टअप पर वे कुछ विशेष जादू करते हैं। बाईं ओर एक कदम / दाईं ओर एक कदम - आप प्रतिबंधों में चलते हैं। उदाहरण के लिए, किसी कारण से एंटिटी फ्रेमवर्क का माइग्रेशन आवश्यक रूप से DbContext
साथ एक ही असेंबली में होना चाहिए। इसका मतलब है कि प्लग इन के अंदर माइग्रेशन को स्टोर करना संभव नहीं होगा।
FluentMigrator
जब यह स्पष्ट हो गया कि ईएफ माइग्रेशन फिट नहीं है, तो मैंने गूगल में एक समाधान की तलाश की और कई ओपन सोर्स माइग्रेटर्स पाए। उनमें से सबसे उन्नत, NuGet पर डाउनलोड की संख्या और GitHub पर सितारों को देखते हुए, FluentMigrator निकला । एफएम बहुत अच्छा है! वह बहुत कुछ जानता है और एक बहुत सुविधाजनक एपीआई है। पहले तो मैंने तय किया कि मुझे यही चाहिए, लेकिन बाद में कई समस्याओं का पता चला।
मुख्य समस्या यह है कि FluentMigrator को पता नहीं है कि एक ही डेटाबेस के भीतर कई संस्करण अनुक्रमों को कैसे ध्यान में रखा जाए। जैसा कि मैंने ऊपर लिखा था, मुझे एक मॉड्यूलर अनुप्रयोग में एक प्रवासी का उपयोग करने की आवश्यकता थी। यह आवश्यक है कि मॉड्यूल (प्लगइन्स) एक-दूसरे से स्वतंत्र रूप से इंस्टॉल और अपडेट किए जा सकते हैं। FluentMigrator में एंड-टू-एंड वर्जन नंबरिंग है। इस वजह से, शेष प्लगइन्स के डेटाबेस संरचना को प्रभावित किए बिना डेटाबेस से एक प्लगइन के माइग्रेशन को निष्पादित / रोल करना असंभव है।
मैंने टैग का उपयोग करके वांछित व्यवहार को व्यवस्थित करने की कोशिश की, लेकिन यह भी काफी नहीं है कि आपको क्या चाहिए। FluentMigrator पूर्ण किए गए माइग्रेशन के लिए टैग जानकारी संग्रहीत नहीं करता है। इसके अलावा, टैग प्रवासियों से बंधे होते हैं, असेंबलियों के नहीं। यह बहुत अजीब है, यह देखते हुए कि प्रवास के लिए प्रवेश बिंदु बिल्कुल विधानसभा है। सिद्धांत रूप में, संभवतः इस तरह से समानांतर संस्करण करना संभव था, लेकिन आपको प्रवासी पर अधिक जटिल आवरण लिखना होगा।
पोर्ट ECM7.Migrator .NET कोर के लिए
शुरुआत में, इस विकल्प पर विचार भी नहीं किया गया था। उस समय, .NET कोर का वर्तमान संस्करण 1.1 था और इसका एपीआई .NET फ्रेमवर्क के साथ खराब संगत था, जिसमें ECM7.Migrator ने काम किया। मुझे यकीन था कि इसे .NET कोर में पोर्ट करना मुश्किल और समय लेने वाला होगा। जब "समाप्त करने" के लिए कोई विकल्प नहीं थे, तो मैंने इसे आज़माने का फैसला किया। कार्य मेरी अपेक्षा से अधिक आसान था। हैरानी की बात है, यह लगभग तुरंत काम किया। केवल मामूली संपादन की आवश्यकता थी। चूंकि प्रवासी का तर्क परीक्षणों द्वारा कवर किया गया था, इसलिए जो सभी स्थान टूट गए थे, वे तुरंत दिखाई दे रहे थे और मैंने जल्दी से उनकी मरम्मत की।
अब मैंने केवल चार DBMS के लिए एडेप्टर पोर्ट किए हैं: MS SQL सर्वर, PostgreSQL, MySQL, SQLite। मैं Oracle के लिए पोर्ट एडाप्टर्स नहीं करता (क्योंकि .NET कोर के लिए अभी भी कोई स्थिर क्लाइंट नहीं है), MS SQL सर्वर CE (क्योंकि यह केवल विंडोज के तहत काम करता है और मेरे पास इसे चलाने के लिए कोई जगह नहीं है) और Firebird (क्योंकि यह बहुत लोकप्रिय नहीं, बाद में बंदरगाह)। सिद्धांत रूप में, यदि आपको इन या अन्य DBMS के लिए प्रदाता बनाने की आवश्यकता है - यह काफी सरल है।
नए प्रवासी के लिए स्रोत कोड GitHub पर है । ट्रैविस सीआई में प्रत्येक डीबीएमएस के लिए परीक्षणों के प्रक्षेपण का विन्यास किया। एक कमांड लाइन उपयोगिता ( .NET कोर ग्लोबल टूल ) लिखी गई थी जिसे आसानी से NuGet से इंस्टॉल किया जा सकता है। डॉक्यूमेंटेशन लिखा है - मैंने विस्तार से और स्पष्ट रूप से लिखने की बहुत कोशिश की और ऐसा लगता है, ऐसा हुआ। आप ले सकते हैं और उपयोग कर सकते हैं!
नाम के बारे में थोड़ा ...
नए प्रवासी पुराने के साथ पिछड़े संगतता नहीं है। वे विभिन्न प्लेटफार्मों पर काम करते हैं और उनके पास एक अलग एपीआई है। इसलिए, प्रोजेक्ट एक अलग नाम के तहत प्रकाशित किया जाता है।
नाम थिंकिंगहोम परियोजना द्वारा चुना गया था, जिसके लिए मैंने एक प्रवासी को पोर्ट किया था। वास्तव में, ECM7.Migrator को उस परियोजना के लिए भी नामित किया गया है जो मैं उस समय काम कर रहा था।
शायद कुछ तटस्थ नाम चुनना बेहतर था, लेकिन मेरे पास कोई अच्छा विकल्प नहीं था। यदि आप यह जानते हैं - टिप्पणियों में लिखें। हर चीज का नाम बदलने में देर नहीं लगती।
संस्करण संख्या 3.0.0 इंगित करती है, क्योंकि नया प्रवासी पुराने की तार्किक निरंतरता है।
जल्दी शुरू करो
तो, चलो एक प्रवासी का उपयोग करके देखें।
सभी डेटाबेस परिवर्तन माइग्रेशन कोड में दर्ज किए जाते हैं - एक प्रोग्रामिंग भाषा में लिखित कक्षाएं (उदाहरण के लिए, सी # में)। माइग्रेशन क्लासेस को Migration
बेस क्लास से थिंकिंगहोम.इग्रेटर.फ्रेमवर्क पैकेज से विरासत में मिला है। उनमें, आपको आधार वर्ग के तरीकों को ओवरराइड करने की आवश्यकता है: Apply
(परिवर्तनों को लागू Apply
) और Revert
(परिवर्तनों को वापस रोल करें)। इन विधियों के अंदर, डेवलपर, एक विशेष एपीआई का उपयोग करते हुए , उन कार्यों का वर्णन करता है , जिन्हें डेटाबेस पर करने की आवश्यकता होती है।
इसके अलावा, माइग्रेशन क्लास को [Migration]
विशेषता के साथ चिह्नित किया जाना चाहिए और उस संस्करण को इंगित करना चाहिए जिसमें डेटाबेस इन परिवर्तनों के बाद जाएगा।
प्रवासन का उदाहरण
using ThinkingHome.Migrator.Framework; [Migration(12)] public class MyTestMigration : Migration { public override void Apply() { // : Database.AddTable("CustomerAddress", new Column("customerId", DbType.Int32, ColumnProperty.PrimaryKey), new Column("addressId", DbType.Int32, ColumnProperty.PrimaryKey)); } public override void Revert() { // : Database.RemoveTable("CustomerAddress"); // , // Revert } }
कैसे चलाना है?
माइग्रेशन एक .dll फ़ाइल में संकलित किए जाते हैं। उसके बाद, आप migrate-database
कंसोल उपयोगिता का उपयोग करके डेटाबेस परिवर्तन कर सकते हैं। आरंभ करने के लिए, इसे NuGet से इंस्टॉल करें।
dotnet tool install -g thinkinghome.migrator.cli
migrate-database
, आवश्यक DBMS प्रकार, कनेक्शन स्ट्रिंग और माइग्रेशन के साथ .dll फ़ाइल का पथ निर्दिष्ट करें।
migrate-database postgres "host=localhost;port=5432;database=migrations;" /path/to/migrations.dll
एपीआई के माध्यम से भागो
आप अपने स्वयं के एप्लिकेशन से एपीआई के माध्यम से पलायन कर सकते हैं। उदाहरण के लिए, आप एक एप्लिकेशन लिख सकते हैं, जो लॉन्च होने पर खुद को वांछित डेटाबेस संरचना बनाता है।
ऐसा करने के लिए, NuGet से ThinkingHome.Migrator पैकेज और अपने प्रोजेक्ट के लिए आवश्यक DBMS में परिवर्तन प्रदाता के साथ पैकेज कनेक्ट करें। उसके बाद, ThinkingHome.Migrator.Migrator
वर्ग का एक उदाहरण बनाएं और इसके Migrate
विधि को कॉल Migrate
, डेटाबेस के आवश्यक संस्करण को एक पैरामीटर के रूप में पारित करें।
var version = -1; // -1 var provider = "postgres"; var connectionString = "host=localhost;port=5432;database=migrations;"; var assembly = Assembly.LoadFrom("/path/to/migrations.dll"); using (var migrator = new Migrator(provider, connectionString, assembly)) { migrator.Migrate(version); }
वैसे, आप FluentMigrator लॉन्च उदाहरण के साथ तुलना कर सकते हैं।
निष्कर्ष
मैंने व्यसनों और जटिल जादू के बिना एक सरल उपकरण बनाने की कोशिश की। लगता है काफी अच्छा काम किया है। परियोजना लंबे समय से क्रूड नहीं हुई है, सब कुछ परीक्षणों में शामिल है, रूसी में विस्तृत प्रलेखन है। यदि आप .NET कोर 2.1 का उपयोग कर रहे हैं, तो एक नया प्रवासी प्रयास करें। सबसे अधिक संभावना है कि आप इसे पसंद करेंगे।