سؤال

كيف يمكنك استرجاع عملية ترحيل Rails الفاشلة؟أتوقع ذلك rake db:rollback سيؤدي إلى التراجع عن الترحيل الفاشل، ولكن لا، فهو يتراجع عن الترحيل السابق (الترحيل الفاشل ناقص واحد).و rake db:migrate:down VERSION=myfailedmigration لا يعمل أيضا.لقد واجهت هذا عدة مرات وهو محبط للغاية.إليك اختبارًا بسيطًا قمت به لتكرار المشكلة:

class SimpleTest < ActiveRecord::Migration
  def self.up
    add_column :assets, :test, :integer
    # the following syntax error will cause the migration to fail
    add_column :asset, :test2, :integer
  end

  def self.down
    remove_column :assets, :test
    remove_column :assets, :test2
  end
end

نتيجة:

==  SimpleTest: migrating =====================================================
-- add_column(:assets, :test, :integer)
   -> 0.0932s
-- add_column(:asset, :error)
rake aborted!
An error has occurred, all later migrations canceled:

wrong number of arguments (2 for 3)

حسنًا، لنرجعها مرة أخرى:

$ rake db:rollback
==  AddLevelsToRoles: reverting ===============================================
-- remove_column(:roles, :level)
   -> 0.0778s
==  AddLevelsToRoles: reverted (0.0779s) ======================================

هاه؟كان ذلك آخر ترحيل لي قبل SimpleTest، وليس الترحيل الفاشل.(وسيكون من الرائع أن يتضمن مخرج الترحيل رقم الإصدار.)

لذلك دعونا نحاول تشغيل عملية الترحيل الفاشلة SimpleTest:

$ rake db:migrate:down VERSION=20090326173033
$

لا يحدث شيء، ولا يوجد مخرج أيضًا.ولكن ربما كان يدير الهجرة على أي حال؟لذلك دعونا نصلح خطأ بناء الجملة في ترحيل SimpleTest، ونحاول تشغيله مرة أخرى.

$ rake db:migrate:up VERSION=20090326173033
==  SimpleTest: migrating =====================================================
-- add_column(:assets, :test, :integer)
rake aborted!
Mysql::Error: Duplicate column name 'test': ALTER TABLE `assets` ADD `test` int(11)

لا.من الواضح أن الهجرة: إلى الأسفل لم تنجح.إنه لا يفشل، إنه فقط لا ينفذ.

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

هل كانت مفيدة؟

المحلول

ولسوء الحظ، يجب تنظيف يدويا الهجرات فشل لماي. الخلية لا يدعم التغييرات تعريف قاعدة بيانات المعاملات.

والقضبان 2،2 يشمل الهجرات المعاملات لشبكة الإنترنت. القضبان 2،3 يشمل الهجرات المعاملات لسكليتي.

وهذا لا يساعد حقا لكم لمشكلتك الآن، ولكن إذا كان لديك اختيار قاعدة بيانات عن المشاريع المستقبلية، أوصي باستخدام واحد مع دعم لDDL المعاملات لأنه يجعل الهجرة أكثر متعة بكثير.

تحديث - وهذا لا يزال صحيحا في عام 2017، على القضبان 4.2.7 و MySQL 5.7، ذكرت من قبل أليخاندرو Babio في إجابة أخرى هنا

.

نصائح أخرى

للانتقال إلى إصدار محدد فقط استخدم:

rake db:migrate VERSION=(the version you want to go to)

ولكن إذا فشلت عملية الترحيل جزئيًا، فسيتعين عليك تنظيفها أولاً.طريقة واحدة ستكون:

  • تحرير down طريقة الترحيل للتراجع عن جزء من up هذا مشغول
  • العودة إلى الحالة السابقة (حيث بدأت)
  • إصلاح الترحيل (بما في ذلك التراجع عن التغييرات التي أجريتها على ملف down)
  • حاول ثانية

حسنًا يا رفاق، إليكم كيفية القيام بذلك بالفعل.لا أعرف ما الذي تتحدث عنه الإجابات المذكورة أعلاه.

  1. اكتشف أي جزء من عملية الترحيل للأعلى نجح.التعليق على تلك الخروج.
  2. قم أيضًا بالتعليق/إزالة جزء الترحيل الذي تم كسره.
  3. قم بتشغيل الترحيل مرة أخرى.والآن سوف يكمل الأجزاء غير المنقطعة من الهجرة، متخطيًا الأجزاء التي تم إنجازها بالفعل.
  4. قم بإلغاء التعليق على أجزاء الترحيل التي علقت عليها في الخطوة 1.

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

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

rake db:migrate RAILS_ENV=test

ويمكنك العودة إلى الحالة السابقة وحاول مرة أخرى مع

rake db:schema:load RAILS_ENV=test

في عام 2015 مع Rails 4.2.1 وMySQL 5.7، لا يمكن إصلاح الترحيل الفاشل باستخدام إجراءات Rake القياسية التي توفرها Rails، كما كان الحال في عام 2009.

لا يدعم MySql التراجع عن بيانات DDL (في دليل ماي إس كيو إل 5.7).ولا يستطيع ريلز فعل أي شيء حيال ذلك.

يمكننا أيضًا التحقق من كيفية قيام Rails بهذه المهمة:الهجرة هي ملفوفة في الصفقة اعتمادًا على كيفية استجابة محول الاتصال :supports_ddl_transactions?.بعد البحث عن هذا الإجراء في مصدر Rails (الإصدار 4.2.1)، وجدت ذلك فقط سكليتي3 و PostgreSql يدعم المعاملات، وعن طريق تقصير غير معتمد.

يحرروبالتالي فإن الإجابة الحالية على السؤال الأصلي:يجب إصلاح عملية ترحيل MySQL الفاشلة يدويًا.

الطريقة السهلة للقيام بذلك هي تضمين جميع إجراءاتك في معاملة:

class WhateverMigration < ActiveRecord::Migration

 def self.up
    ActiveRecord::Base.transaction do
...
    end
  end

  def self.down
    ActiveRecord::Base.transaction do
...
    end
  end

end

كما أشار Luke Francl، "جداول MyISAM الخاصة بـ MySql لا تدعم المعاملات" - ولهذا السبب قد تفكر في تجنب MySQL بشكل عام أو على الأقل MyISAM بشكل خاص.

إذا كنت تستخدم InnoDB الخاص بـ MySQL، فإن ما ورد أعلاه سيعمل بشكل جيد.سيتم التراجع عن أي أخطاء في الأعلى أو الأسفل.

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

وتشغيل مجرد هجرة أسفل من وحدة التحكم:

HTTP: //gilesbowkett.blogspot كوم / 2007/07 / كم إلى استخدام الهجرات-من-console.html (من خلال النقر على باسط له)

وكان الخطأ المطبعي (في "add_column"):

<اقتباس فقرة>   

ومواطنه self.up

add_column :medias, :title, :text
add_colunm :medias, :enctype, :text
     

ونهاية

     

ومواطنه self.down

remove_column :medias, :title
remove_column :medias, :enctype   
     

ونهاية

وثم مشكلتك (لا يمكن التراجع عن الهجرة فشلت جزئيا). بعد فشل بعض غوغلينغ ركضت هذا:

<اقتباس فقرة>   

ومواطنه self.up

remove_column :medias, :title
add_column :medias, :title, :text
add_column :medias, :enctype, :text
     

ونهاية

     

ومواطنه self.down

remove_column :medias, :title
remove_column :medias, :enctype
     

ونهاية

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

والجواب اليخاندرو Babio إلى ما فوق يوفر أفضل إجابة الحالية.

واحد تفاصيل إضافية أريد أن أضيف:

عند فشل الهجرة myfailedmigration، فإنه لا يعتبر كما هو مطبق، وهذا يمكن أن يتم التحقق منها عن طريق تشغيل rake db:migrate:status، والتي من شأنها أن تظهر إخراج مشابه لما يلي:

$  rake db:migrate:status
database: sample_app_dev

 Status   Migration ID    Migration Name
--------------------------------------------------
   up      20130206203115  Create users
   ...
   ...
   down    20150501173156  Test migration

وهذا الأثر المتبقي من add_column :assets, :test, :integer يتم تنفيذه على الهجرة فشل سيتعين عكس على مستوى قاعدة البيانات مع استعلام alter table assets drop column test;.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top