Źle nazwałem kolumnę hased_password
zamiast hashed_password
.
Jak zaktualizować schemat bazy danych, używając migracji do zmiany nazwy tej kolumny?
Źle nazwałem kolumnę hased_password
zamiast hashed_password
.
Jak zaktualizować schemat bazy danych, używając migracji do zmiany nazwy tej kolumny?
Odpowiedzi:
rename_column :table, :old_column, :new_column
Aby to zrobić, prawdopodobnie będziesz chciał utworzyć osobną migrację. (Zmień nazwę, FixColumnName
jak chcesz.):
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Następnie edytuj migrację, aby wykonać swoją wolę:
# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
def self.up
rename_column :table_name, :old_column, :new_column
end
def self.down
# rename back if you need or do something else or do nothing
end
end
W przypadku Rails 3.1 użyj:
Chociaż nadal obowiązują metody up
i down
, Rails 3.1 otrzymuje change
metodę, która „wie, jak przeprowadzić migrację bazy danych i odwrócić ją, gdy migracja zostanie wycofana bez potrzeby zapisywania oddzielnej metody wyłączania”.
Aby uzyskać więcej informacji, zobacz „ Migracje aktywnych rekordów ”.
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Jeśli zdarzy się, że masz całą grupę kolumn do zmiany nazwy lub coś, co wymagałoby powtarzania nazwy tabeli w kółko:
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
Możesz użyć tego, change_table
aby zachować trochę porządek:
class FixColumnNames < ActiveRecord::Migration
def change
change_table :table_name do |t|
t.rename :old_column1, :new_column1
t.rename :old_column2, :new_column2
...
end
end
end
Więc db:migrate
jak zwykle lub jakkolwiek zajmujesz się swoją działalnością.
W przypadku szyn 4:
Podczas tworzenia Migration
zmiany nazwy kolumny Rails 4 generuje change
metodę zamiast up
i down
jak wspomniano w powyższej sekcji. Wygenerowana change
metoda to:
$ > rails g migration ChangeColumnName
który utworzy plik migracji podobny do:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
self.up
, nie powiedziałbym, że self.down
„ zawsze powinno być odwrotnie”. W zależy od kontekstu migracji. Samo umieszczenie „przeciwieństwa” może nie być „właściwym” spadkiem migracji.
def self.up
i def self.down
ze def change
i to będzie wiedzieć, jak cofnąć.
change
metoda nie jest pełnym dowodem, więc zwykle używaj up
i down
metod do złożonych migracji.
Moim zdaniem w tym przypadku lepiej użyć rake db:rollback
, a następnie edytować migrację i ponownie uruchomić rake db:migrate
.
Jeśli jednak w kolumnie znajdują się dane, których nie chcesz stracić, użyj rename_column
.
Jeśli kolumna jest już zapełniona danymi i jest uruchomiona w produkcji, zaleciłbym podejście krok po kroku, aby uniknąć przestojów w produkcji podczas oczekiwania na migrację.
Najpierw utworzę migrację bazy danych, aby dodać kolumny z nowymi nazwami i wypełnić je wartościami ze starej nazwy kolumny.
class AddCorrectColumnNames < ActiveRecord::Migration
def up
add_column :table, :correct_name_column_one, :string
add_column :table, :correct_name_column_two, :string
puts 'Updating correctly named columns'
execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
end
end
def down
remove_column :table, :correct_name_column_one
remove_column :table, :correct_name_column_two
end
end
Następnie dokonałbym właśnie tej zmiany i pchnąłbym ją do produkcji.
git commit -m 'adding columns with correct name'
Potem, gdy zatwierdzenie zostanie wprowadzone do produkcji, zacznę działać.
Production $ bundle exec rake db:migrate
Następnie zaktualizowałbym wszystkie widoki / kontrolery, które odwoływały się do starej nazwy kolumny do nowej nazwy kolumny. Uruchom mój zestaw testów i zatwierdź tylko te zmiany. (Po upewnieniu się, że działa lokalnie i najpierw przejściu wszystkich testów!)
git commit -m 'using correct column name instead of old stinky bad column name'
Potem zmusiłbym to zobowiązanie do produkcji.
W tym momencie możesz usunąć oryginalną kolumnę bez obawy o jakiekolwiek przestoje związane z samą migracją.
class RemoveBadColumnNames < ActiveRecord::Migration
def up
remove_column :table, :old_name_column_one
remove_column :table, :old_name_column_two
end
def down
add_column :table, :old_name_column_one, :string
add_column :table, :old_name_column_two, :string
end
end
Następnie wypchnij najnowszą migrację do produkcji i uruchom ją bundle exec rake db:migrate
w tle.
Zdaję sobie sprawę, że jest to trochę bardziej zaangażowane w proces, ale wolę to zrobić niż mieć problemy z migracją produkcji.
execute "Update table_name set correct_name_column_one = old_name_column_one"
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
Pod Available Transformations
rename_column(table_name, column_name, new_column_name):
Zmienia nazwę kolumny, ale zachowuje typ i treść.
rename_column
.
Uruchom poniższe polecenie, aby utworzyć plik migracji:
rails g migration ChangeHasedPasswordToHashedPassword
Następnie w pliku wygenerowanym w db/migrate
folderze napisz rename_column
jak poniżej:
class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Niektóre wersje Ruby on Rails obsługują metodę migracji w górę / w dół, a jeśli masz migrację w górę / w dół, to:
def up
rename_column :table_name, :column_old_name, :column_new_name
end
def down
rename_column :table_name, :column_new_name, :column_old_name
end
Jeśli masz change
metodę migracji, to:
def change
rename_column :table_name, :column_old_name, :column_new_name
end
Aby uzyskać więcej informacji, możesz przenieść: Ruby on Rails - Migrations lub Active Record Migrations .
Jeśli twój kod nie jest współdzielony z innym, najlepszym rozwiązaniem jest dokonanie rake db:rollback
edycji nazwy kolumny podczas migracji irake db:migrate
. Otóż to
Możesz napisać kolejną migrację, aby zmienić nazwę kolumny
def change
rename_column :table_name, :old_name, :new_name
end
Otóż to.
rake db:rollback
to świetna sugestia. Ale jak powiedziałeś, tylko jeśli migracja nie została jeszcze przesunięta.
Alternatywnie, jeśli nie jesteś żonaty z ideą migracji, istnieje atrakcyjny klejnot dla ActiveRecord, który będzie automatycznie obsługiwał zmiany nazw dla ciebie, styl Datamapper. Wszystko, co musisz zrobić, to zmienić nazwę kolumny w swoim modelu (i upewnij się, że umieściłeś Model.auto_upgrade! Na dole swojego modelu.rb) i viola! Baza danych jest aktualizowana na bieżąco.
https://github.com/DAddYE/mini_record
Uwaga: Aby zapobiec konfliktom, musisz nuke db / schema.rb
Wciąż w fazie beta i oczywiście nie dla wszystkich, ale wciąż przekonujący wybór (obecnie używam go w dwóch nietrywialnych aplikacjach produkcyjnych bez problemów)
Jeśli musisz zmienić nazwy kolumn, musisz utworzyć symbol zastępczy, aby uniknąć błędu duplikatu nazwy kolumny . Oto przykład:
class SwitchColumns < ActiveRecord::Migration
def change
rename_column :column_name, :x, :holder
rename_column :column_name, :y, :x
rename_column :column_name, :holder, :y
end
end
Jeśli obecne dane nie są dla Ciebie ważne, możesz po prostu usunąć oryginalną migrację, używając:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
Bez cudzysłowów wprowadź zmiany w oryginalnej migracji i ponownie uruchom migrację w górę, wykonując:
rake db:migrate
W przypadku Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
Ręcznie możemy użyć poniższej metody:
Możemy edytować migrację ręcznie, jak:
otwarty app/db/migrate/xxxxxxxxx_migration_file.rb
Zaktualizuj hased_password
dohashed_password
Uruchom poniższe polecenie
$> rake db:migrate:down VERSION=xxxxxxxxx
Następnie usunie migrację:
$> rake db:migrate:up VERSION=xxxxxxxxx
Spowoduje to dodanie migracji wraz ze zaktualizowaną zmianą.
Biegać rails g migration ChangesNameInUsers
(lub jakkolwiek chcesz to nazwać)
Otwórz właśnie utworzony plik migracji i dodaj ten wiersz w metodzie (pomiędzy def change
i end
):
rename_column :table_name, :the_name_you_want_to_change, :the_new_name
Zapisz plik i uruchom rake db:migrate
w konsoli
Sprawdź swoje schema.db
, aby zobaczyć, czy nazwa rzeczywiście się zmieniła w bazie danych!
Mam nadzieję że to pomoże :)
Spójrzmy prawdzie w KISS . Wystarczy trzy proste kroki. Poniższe działa dla Railsów 5.2 .
rails g migration RenameNameToFullNameInStudents
rails g RenameOldFieldToNewFieldInTableName
- w ten sposób jest całkowicie jasne dla opiekunów bazy kodu później. (użyj liczby mnogiej jako nazwy tabeli).
# I prefer to explicitly write the
w górę w and
dółmethods.
# ./db/migrate/20190114045137_rename_name_to_full_name_in_students.rb
class RenameNameToFullNameInStudents < ActiveRecord::Migration[5.2]
def up
# rename_column :table_name, :old_column, :new_column
rename_column :students, :name, :full_name
end
def down
# Note that the columns are reversed
rename_column :students, :full_name, :name
end
end
rake db:migrate
I startujesz w wyścigach!
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Otwórz ten plik migracji i zmodyfikuj go jak poniżej (Podaj oryginał table_name
)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Otwórz konsolę Ruby on Rails i wprowadź:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
Możesz to zrobić na dwa sposoby:
W tym typie automatycznie uruchamia jego kod zwrotny podczas wycofywania.
def change
rename_column :table_name, :old_column_name, :new_column_name
end
Do tego typu uruchamia metodę „up” kiedy rake db:migrate
i uruchamia metodę „down”, gdy rake db:rollback
:
def self.up
rename_column :table_name, :old_column_name, :new_column_name
end
def self.down
rename_column :table_name,:new_column_name,:old_column_name
end
Jestem na szynach 5.2 i próbuję zmienić nazwę kolumny na urządzeniu użytkownika.
rename_column
nieco pracował dla mnie, ale liczba pojedyncza :table_name
rzucił „tabeli użytkownika nie znaleziono” błąd. Liczba mnoga zadziałała dla mnie.
rails g RenameAgentinUser
Następnie zmień plik migracji na ten:
rename_column :users, :agent?, :agent
Gdzie: agent? to stara nazwa kolumny.
Aktualizacja - bliskim kuzynem create_table jest change_table, służący do zmiany istniejących tabel. Jest on używany w podobny sposób do create_table, ale obiekt przekazany do bloku zna więcej sztuczek. Na przykład:
class ChangeBadColumnNames < ActiveRecord::Migration
def change
change_table :your_table_name do |t|
t.rename :old_column_name, :new_column_name
end
end
end
Ten sposób jest bardziej wydajny, jeśli robimy to z innymi metodami modyfikacji, takimi jak: usuń / dodaj indeks / usuń indeks / dodaj kolumnę, np. Możemy zrobić dalej, jak:
# Rename
t.rename :old_column_name, :new_column_name
# Add column
t.string :new_column
# Remove column
t.remove :removing_column
# Index column
t.index :indexing_column
#...
Po prostu wygeneruj migrację za pomocą polecenia
rails g migration rename_hased_password
Po tej edycji migracji dodaj następujący wiersz w metodzie zmiany
rename_column :table, :hased_password, :hashed_password
To powinno załatwić sprawę.
Zmiany w migracji Rails 5
na przykład:
szyny g model Student student_name: string wiek: liczba całkowita
jeśli chcesz zmienić kolumnę nazwa_ studenta jako nazwę
Uwaga: - jeśli nie uruchomisz szyny db: migruj
Możesz wykonać następujące kroki
szyny d model Student student_name: string wiek: liczba całkowita
Spowoduje to usunięcie wygenerowanego pliku migracji. Teraz możesz poprawić nazwę kolumny
szyny g model Nazwa ucznia: wiek wiek: liczba całkowita
Jeśli przeprowadziłeś migrację (rails db: migrate), wykonaj następujące opcje, aby zmienić nazwę kolumny
migracja rails g RemoveStudentNameFromStudent student_name: string
szyny g migracja AddNameToStudent name: string
rails g migration RemoveStudentNameFromStudentS student_name:string
(uczniowie są w liczbie mnogiej)?