ThinkingHome.Migrator - ترحيل نسخة مخطط قاعدة البيانات على منصة .NET Core

مرحبًا أصدرت اليوم إصدارًا جديدًا من ThinkingHome.Migrator - وهي أداة للترحيل المحدث لمخطط قاعدة البيانات إلى النظام الأساسي .NET Core.


الحزم المنشورة في NuGet ، كتب وثائق مفصلة . يمكنك بالفعل استخدام الترحيل الجديد ، وسأخبرك كيف ظهر ، ولماذا يحتوي على الإصدار رقم 3.0.0 (على الرغم من أن هذا هو الإصدار الأول) ولماذا هو مطلوب عند وجود EF Migrations و FluentMigrator .


كيف بدأ كل شيء


منذ 9 سنوات ، في عام 2009 ، عملت كمطور ASP.NET. عندما أصدرنا مشروعنا ، بقي شخص خاص مستيقظًا حتى وقت متأخر ، وفي نفس الوقت قام بتحديث الملفات الموجودة على الخادم ، قام بتنفيذ نصوص SQL باستخدام يديه لتحديث قواعد البيانات في المنتج. لقد بحثنا عن أداة تقوم بذلك تلقائيًا ووجدنا مشروع Migrator.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 ). لذلك ، لم نتعب أنفسنا بشكل خاص للتأكد من عودة تغييراتنا إلى المشروع الأصلي - لقد شاهدنا نسختنا واستخدمناها بأنفسنا. مع مرور الوقت ، أعدنا كتابة معظم المشروع ، وأصبحت المشرف الرئيسي عليه. ثم قمت بنشر كود مهاجرنا على كود جوجل وكتبت مقالة عن هبر . لذلك كان هناك ECM7.


أثناء العمل على المهاجر ، نعيد كتابته بالكامل تقريبًا. في نفس الوقت ، قاموا بتبسيط API قليلاً وغطوا كل شيء باختبارات تلقائية. أنا شخصياً استمتعت حقًا باستخدام ما حدث. على عكس المهاجر الأصلي ، كان هناك شعور بالموثوقية ولم يكن هناك شعور بأن السحر الغريب يحدث.


كما اتضح ، لم أحب فقط مهاجرنا. على حد علمي ، تم استخدامه في الشركات الكبيرة إلى حد ما. أعرف عن ABBYY و BARS Group و concert.ru. إذا قمت بكتابة استعلام البحث "ecm7 ترحيل" ، يمكنك أن ترى في نتائج النتائج حوله ، الإشارات في السيرة الذاتية ، أوصاف الاستخدام في عمل الطالب. في بعض الأحيان تلقيت رسائل من الغرباء مع أسئلة أو كلمات الامتنان.


بعد عام 2012 ، لم يتطور المشروع تقريبًا. غطت قدراتها الحالية جميع المهام التي كانت لدي ولم أرى حاجة لإنهاء شيء ما.


ThinkingHome.Migrator


في العام الماضي ، بدأت العمل في مشروع على .NET Core. كان من الضروري تمكين ربط المكونات الإضافية ، ويجب أن تكون المكونات الإضافية قادرة على إنشاء بنية قاعدة البيانات اللازمة لأنفسهم من أجل تخزين بياناتهم هناك. هذه مجرد مهمة ، حيث يكون المهاجر مناسبًا تمامًا.


هجرات Ef


لقد استخدمت Entity Framework Core للعمل مع قاعدة البيانات ، لذلك كان أول شيء جربته هو EF Migrations. لسوء الحظ ، اضطررت على الفور للتخلي عن فكرة استخدامها.


تقوم عمليات ترحيل Entity Framework بسحب مجموعة من التبعيات إلى المشروع ، وعند بدء التشغيل تقوم ببعض السحر الخاص. خطوة إلى اليسار / خطوة إلى اليمين - تواجه قيودًا. على سبيل المثال ، يجب أن تكون عمليات ترحيل Entity Framework لسبب ما بالضرورة في نفس التجميع مع DbContext . هذا يعني أنه لن يكون من الممكن تخزين عمليات الترحيل داخل المكونات الإضافية.


Fluentmigrator


عندما أصبح من الواضح أن EF Migrations لم تكن مناسبة ، بحثت عن حل في جوجل ووجدت العديد من المهاجرين مفتوح المصدر. أكثرها تقدمًا ، استنادًا إلى عدد التنزيلات على NuGet والنجوم على GitHub ، تبين أنها FluentMigrator . وزير الخارجية جيد جدا! إنه يعرف الكثير ولديه واجهة برمجة تطبيقات مريحة للغاية. قررت في البداية أن هذا هو ما أحتاجه ، ولكن تم اكتشاف العديد من المشاكل في وقت لاحق.


تكمن المشكلة الرئيسية في أن FluentMigrator لا يعرف كيف يأخذ في الاعتبار تسلسل العديد من الإصدارات داخل نفس قاعدة البيانات. كما كتبت أعلاه ، كنت بحاجة إلى استخدام مهاجر في تطبيق معياري. من الضروري تثبيت الوحدات (الإضافات) وتحديثها بشكل مستقل عن بعضها البعض. FluentMigrator لديه ترقيم الإصدار من طرف إلى طرف. ولهذا السبب ، من المستحيل تنفيذ / استعادة ترحيل مكون إضافي واحد من قاعدة البيانات دون التأثير على بنية قاعدة البيانات للمكونات الإضافية المتبقية.


حاولت تنظيم السلوك المطلوب باستخدام العلامات ، ولكن هذا ليس بالضبط ما تحتاجه. لا يخزن FluentMigrator معلومات العلامات لعمليات الترحيل المكتملة. بالإضافة إلى ذلك ، ترتبط العلامات بعمليات الترحيل وليس التجميعات. هذا غريب جدًا ، نظرًا لأن نقطة الدخول للهجرة هي بالضبط التجميع. من حيث المبدأ ، ربما كان من الممكن عمل نسخ متوازية بهذه الطريقة ، ولكنك تحتاج إلى كتابة غلاف معقد إلى حد ما فوق المهاجر.


منفذ ECM7.Migrator إلى .NET Core


في البداية ، لم يؤخذ هذا الخيار في الاعتبار. في ذلك الوقت ، كان الإصدار الحالي من .NET Core هو 1.1 وكانت واجهة برمجة التطبيقات الخاصة به غير متوافقة بشكل جيد مع .NET Framework ، حيث عملت ECM7.Migrator. كنت متأكدًا من أن نقله إلى .NET Core سيكون صعبًا ويستغرق وقتًا طويلاً. عندما لم تكن هناك خيارات لـ "أخذ النهاية" ، قررت أن أجربها. كانت المهمة أسهل مما توقعت. والمثير للدهشة ، أنها عملت على الفور تقريبا. كانت التعديلات الطفيفة فقط مطلوبة. منذ أن تم تغطية منطق المهاجر من خلال الاختبارات ، كانت جميع الأماكن التي اندلعت مرئية على الفور وقمت بإصلاحها بسرعة.


لقد قمت الآن بنقل محولات لأربع DBMS فقط: MS SQL Server و PostgreSQL و MySQL و SQLite. لم أقم بتوصيل محولات لـ Oracle (حيث لا يوجد حتى الآن عميل مستقر لـ .NET Core) و MS SQL Server CE (نظرًا لأنه يعمل فقط ضمن Windows وليس لدي مكان لتشغيله) و Firebird (لأنه لا تحظى بشعبية كبيرة ، المنفذ لاحقًا). من حيث المبدأ ، إذا كنت بحاجة إلى إنشاء موفري لهذه DBMS أو غيرها - فهذا أمر بسيط للغاية.


شفرة المصدر للمُرحِّل الجديد موجودة على GitHub . تكوين إطلاق الاختبارات لكل DBMS في Travis CI. تمت كتابة أداة سطر أوامر ( .NET Core Global Tool ) يمكن تثبيتها بسهولة من NuGet . تم كتابة الوثائق - حاولت جاهدة أن أكتب بالتفصيل وبشكل واضح ، ويبدو أن ذلك حدث. يمكنك أن تأخذ واستخدام!


قليلا عن الاسم ...


المهاجر الجديد ليس لديه توافق عكسي مع القديم. إنهم يعملون على منصات مختلفة ولديهم واجهة برمجة تطبيقات مختلفة. لذلك ، تم نشر المشروع تحت اسم مختلف.


تم اختيار الاسم من خلال مشروع ThinkingHome ، الذي قمت بنقل مهاجر له. في الواقع ، تم تسمية ECM7.Migrator أيضًا للمشروع الذي كنت أعمل عليه في تلك اللحظة.


ربما كان من الأفضل اختيار اسم محايد ، ولكن لم يخطر ببالي أن لدي أي خيارات جيدة. إذا كنت تعرف هذا - اكتب في التعليقات. لم يفت الأوان لإعادة تسمية كل شيء.


وأشار رقم الإصدار 3.0.0 ، لأنه المهاجر الجديد هو استمرار منطقي للمسنين.


بداية سريعة


لذا ، دعنا نحاول استخدام مهاجر.


يتم تسجيل جميع تغييرات قاعدة البيانات في رمز الترحيل - الفئات مكتوبة بلغة برمجة (على سبيل المثال ، في C #). ترث فئات الترحيل من فئة Migration الأساسية من ThinkingHome.Migrator.Framework package. فيها ، تحتاج إلى تجاوز طرق الفئة الأساسية: 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 

يعمل من خلال API


يمكنك تنفيذ عمليات الترحيل من خلال واجهة برمجة التطبيقات من تطبيقك الخاص. على سبيل المثال ، يمكنك كتابة تطبيق ينشئ عند إنشائه بنية قاعدة البيانات المطلوبة.


للقيام بذلك ، قم بتوصيل حزمة ThinkingHome.Migrator من NuGet والحزمة مع موفر التحويل لنظام إدارة قواعد البيانات (DBMS) المطلوب لمشروعك. بعد ذلك ، قم بإنشاء مثيل من فئة ThinkingHome.Migrator.Migrator واستدعاء أسلوب 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 Core 2.1 ، فجرّب ترحيلًا جديدًا . على الأرجح ستعجبك أيضًا.

Source: https://habr.com/ru/post/ar414867/


All Articles