2012-01-10 13 views
31

Nie mogę znaleźć opcji lub czegoś, co pozwala mi pominąć migracje.Jak pominąć migracje zakończone niepowodzeniem? (rake db: migrate)

Wiem o czym myślisz: „nigdy nie powinno się tego robić ...”

muszę pominąć migracji sprawia, że ​​zmiany w poszczególnych rejestrów użytkowników, które nie istnieją w moim rozwoju bazy . Nie chcę zmieniać migracji, ponieważ nie jest ona częścią źródła, z którym mam pracować. Czy istnieje sposób na pominięcie migracji lub pominięcie migracji zakończonych niepowodzeniem?

Z góry dziękuję!

Odpowiedz

53

Myślę, że powinieneś naprawić obraźliwe migracje, aby były mniej wrażliwe, domyślam się, że wystarczy kilka oświadczeń if i być może rescue.

Ale jeśli naprawienie migracji naprawdę nie jest opcją, możesz udawać ją na różne sposoby. Po pierwsze, możesz po prostu skomentować metody migracji, uruchomić rake db:migrate, a następnie odkomentować (lub przywrócić) nieprawidłową migrację.

Możesz również sfałszować go w bazie danych, ale tego rodzaju szykany nie są zalecane, chyba że wiesz, co robisz i nie masz nic przeciwko ręcznemu naprawianiu rzeczy, gdy (nieuchronnie) popełnisz błąd. W bazie danych znajduje się tabela o nazwie schema_migrations z pojedynczą kolumną o nazwie version; ta tabela jest używana przez db:migrate, aby śledzić, które migracje zostały zastosowane. Wszystko, co musisz zrobić, to wstawić odpowiednią wartość version, a rake db:migrate pomyśli, że migracja została wykonana. Znajdź plik migracji wykraczająca:

db/migrate/99999999999999_XXXX.rb 

następnie przejść do bazy danych i powiedzieć:

insert into schema_migrations (version) values ('99999999999999'); 

gdzie 99999999999999 jest, oczywiście, liczba od nazwy pliku migracji jest. Uruchomienie rake db:migrate powinno pomijać tę migrację.

Z trzecią opcją skorzystam z trzeciej opcji, a do uzupełnienia dodam tylko opcję "hack schema_versions".

+0

Ya, ja po prostu poszedł do przodu i wyciąć migracje naruszające tymczasowo. Osobiście utworzyłem odpowiednie instrukcje If lub po prostu sprawdziłem w środowisku produkcyjnym, ale najwyraźniej osoba, która obsługuje migracje, nie wierzy w używanie db: migrate podczas rozwijania = P Dzięki – hmind

+0

@hmind: "osoba, która obsługuje migracje nie wierzą w używanie db: migrate podczas rozwijania ". O mój. Publikowanie w swoich systemach produkcyjnych musi być super radosną zabawą! –

+2

Na szczęście nie poradzę sobie z tym ani haha ​​ – hmind

1

Zamiast pominąć migrację można zrobić migracja mądry, dodając niektóre jeśli do niej, dzięki czemu można sprawdzić „specyficzne użytkowników”

+0

Tak, to byłby to, co zrobiłbym, gdybym napisał migrację. Ale ja nie chciałem i nie chcę zepsuć części źródła, której naprawdę nie powinienem dotykać, więc po prostu skończyłem je tymczasowo. – hmind

14

Jest to dobry sposób, aby zrobić to za błędy jednorazowych.

db:migrate:up VERSION=my_version

ten będzie działał "w górę" działania jednego migracji specyficznej za. (Jest też odwrotnie, jeśli tego potrzebujesz, po prostu zamień "up" na "down".) W ten sposób możesz albo uruchomić przyszłą migrację, która sprawi, że starsza (którą musisz pominąć) pracować, albo po prostu uruchomić każdy migracja przed nim selektywnie.

Wierzę również, że można przerobić migracje w ten sposób:

rake db:migrate:redo VERSION=my_version

nie próbowałem tej metody osobiście, więc YMMV.

1

czasami konieczne jest ponowne wypełnienie schema_migrations stół zdecydowanie poprawnych migracje ... tylko do tego celu Stworzyłem tę metodę

def self.insert_missing_migrations(stop_migration=nil) 
    files = Dir.glob("db/migrate/*") 
    timestamps = files.collect{|f| f.split("/").last.split("_").first} 
    only_n_first_migrations = timestamps.split(stop_migration).first 

    only_n_first_migrations.each do |version| 
    sql = "insert into `schema_migrations` (`version`) values (#{version})" 
    ActiveRecord::Base.connection.execute(sql) rescue nil 
    end 
end 

można skopiować i wkleić go do każdy model chcesz i używać go z konsoli

YourModel.insert_missing_migrations("xxxxxxxxxxxxxx") 

(lub jakiś inny)

gdzie "xxxxxxxxxxxxxx" - jest datownik migracji przed którym chce się zatrzymać wstawianie (można zostawić puste)

!!! używaj go tylko, jeśli absolutnie rozumiesz, jaki wynik otrzymasz !!!

10

Miałem problem, gdzie miałem migrację, aby dodać tabelę, która już istnieje, więc w moim przypadku musiałem pominąć tę migrację, jak również, ponieważ byłem coraz błąd

SQLite3::SQLException: table "posts" already exists: CREATE TABLE "posts" 

po prostu skomentował zawartość metody create table, przeprowadził migrację, a następnie odkomentował ją. Jest to rodzaj ręcznego sposobu obejścia tego, ale zadziałało. Zobacz poniżej:

class CreatePosts < ActiveRecord::Migration 
    def change 
    # create_table :posts do |t| 
    # t.string :title 
    # t.text :message 
    # t.string :attachment 
    # t.integer :user_id 
    # t.boolean :comment 
    # t.integer :phase_id 

    # t.timestamps 
    # end 
    end 
end 
+0

To jest po prostu świetne !!! Nie mogę uwierzyć, że o tym nie myślałem. Całkowicie pracował. – helpse

7

Jeśli musisz to zrobić, migracja aplikacji jest pomieszana!

Wstawki wszystkie brakujące migracje:

def insert(xxx) 
    ActiveRecord::Base.connection.execute("insert into schema_migrations (version) values (#{xxx})") rescue nil 
end 

files = Dir.glob("db/migrate/*") 
files.collect { |f| f.split("/").last.split("_").first }.map { |n| insert(n) } 
+1

Niekoniecznie. Na przykład, jeśli pg_restore produkcyjnej bazy danych do komputera programistycznego, aby rozwiązać problem z danymi produkcyjnymi. Nie mów tak szybko, aby powiedzieć komuś, że robią to źle, gdy nie masz wszystkich informacji. –

+0

@MikeBethany: W moim przypadku, kiedy musiałem go użyć, wszystko było wielkim bałaganem i nie miałem czasu, aby zrozumieć, dlaczego tak się stało. O pg_restore, powinien również przywrócić tabelę "schema_migrations", jak sądzę, prawda? – Dorian

+0

Tak, oczywiście tabela 'schema_migrations' jest po prostu tabelą w bazie danych. Ponownie czytając tytuł mogę zobaczyć inną interpretację. Pierwotnie czytałem to jako "Nie pisałeś poprawnie swoich migracji". Myślę, że masz na myśli "problem z migracjami". Ale to oczywiste, stąd pytanie, więc założyłem, że "ty spieprzyłeś". Mój błąd. –

Powiązane problemy