26 Вопрос: Как я могу переименовать столбец базы данных в миграции Ruby on Rails?

вопрос создан в Thu, Mar 3, 2016 12:00 AM

Я неправильно назвал столбец hased_password вместо hashed_password.

Как обновить схему базы данных, используя миграцию для переименования этого столбца?

    
1384
26 ответов                              26                         
rename_column :table, :old_column, :new_column

Update:

Возможно, вы захотите создать отдельную миграцию для этого. (Переименуйте FixColumnName как хотите)

script/generate migration FixColumnName
# creates  db/migrate/xxxxxxxxxx_fix_column_name.rb

Затем отредактируйте миграцию, чтобы выполнить свою волю.

# 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

Обновление для Rails 3.1

Хотя методы up и down по-прежнему применяются. Rails 3.1 получает метод change, который "знает, как перенести вашу базу данных и отменить ее, когда миграция откатывается без нужно написать отдельный метод "

rails g migration FixColumnName

class FixColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

Если вам нужно переименовать целую группу столбцов или что-то, что потребовало бы повторения имени таблицы снова и снова.

rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...

Вы можете использовать change_table, чтобы держать вещи немного аккуратнее.

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

Спасибо, Luke & Turadg, для поднятия темы.

Тогда просто наберите db:migrate как обычно, либо займитесь своим делом.

Обновление для Rails 4

При создании Migration, как для переименования столбца, Rails 4 генерирует метод change вместо up и down, как упомянуто в ответе выше. Сгенерированный метод change выглядит следующим образом:

$ > rails g migration ChangeColumnName

, который создаст файл миграции, подобный следующему:

class ChangeColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
    
2213
2015-12-04 19: 18: 33Z
  1. self.down должен всегда быть противоположностью self.up, поэтому "если вам нужно или делать что-то еще, или ничего не делать" isn ' Т действительно рекомендуется. Просто сделайте: rename_column: table_name,: new_column,: old_column
    2011-08-29 15: 21: 11Z
  2. Хотя это нормальная практика, чтобы вернуться к тому, что вы сделали в self.up, я бы не сказал, что self.down "должно всегда быть противоположным". В зависимости от контекста вашей миграции. Простое «противоположное» не может быть «правильным» переносом.
    2011-08-29 16: 36: 24Z
  3. В Rails 3.1 вы можете заменить def self.up и def self.down на def change, и он будет знать, как выполнить откат.
    2011-09-09 21: 57: 32Z
  4. Turadg - * он будет знать, как откатить большую часть времени. Я считаю, что метод change не является полным доказательством, поэтому склонны использовать методы up и down для сложных миграций.
    2014-10-19 09: 20: 47Z
  5. Удаляет ли переименование индекс?
    2015-04-12 11: 43: 24Z

IMO, в этом случае лучше использовать rake db:rollback. Затем отредактируйте миграцию и снова введите rake db:migrate. Однако, если у вас есть данные в столбце, которые вы не хотите терять, используйте rename_column.

    
68
2016-03-03 21: 51: 09Z
  1. Даже в «команде из одного», если у вас запущено несколько экземпляров приложения, скажем, в разных средах или на нескольких компьютерах, управление отредактированными миграциями является основной боль. Я редактирую миграцию только в том случае, если я просто создал ее и понял, что это неправильно, и еще нигде не запускал ее буквально.
    2013-12-09 01: 18: 08Z
  2. После этого мне пришлось перезапустить сервер.
    2015-09-06 19: 03: 24Z
  3. Этот метод следует использовать только в ситуации, когда ваши изменения еще не объединены с вашей производственной веткой, а другие не зависят от сохранения данных. В большинстве случаев это НЕ предпочтительный метод.
    2017-01-03 18: 31: 27Z
  4. никогда такого не делают.
    2017-02-23 06: 37: 40Z
  5. Я хотел бы сказать своей команде: «Миграции бесплатны». Стоимость редактирования миграции, выпущенной на волю, высока: однажды я потратил несколько часов выяснить, почему мой код не работал, прежде чем я понял, что другой член команды вернулся и отредактировал миграцию, которую я уже запустил. Так что не редактируйте существующую миграцию, используйте новую для изменения схемы, потому что ... ... "Миграции бесплатны!" (это не совсем так, но это важно)
    2017-09-03 23: 58: 49Z

Если столбец уже заполнен данными и находится в рабочем состоянии, я бы рекомендовал пошаговый подход, чтобы избежать простоев в производстве в ожидании миграции.

Сначала я бы создал миграцию базы данных, чтобы добавить столбцы с новыми именами и заполнить их значениями из старого имени столбца.

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

Тогда я бы зафиксировал это изменение и запустил его в производство.

git commit -m 'adding columns with correct name'

Затем, как только коммит будет запущен в производство, я запускаю.

Production $ bundle exec rake db:migrate

Затем я обновил бы все представления /контроллеры, которые ссылались на старое имя столбца, на новое имя столбца. Запустите мой набор тестов и внесите только эти изменения. (Убедившись, что он работает локально и сначала пройдя все тесты!)

git commit -m 'using correct column name instead of old stinky bad column name'

Тогда я бы подтолкнул этот коммит к производству.

Теперь вы можете удалить исходный столбец, не беспокоясь о простоях, связанных с самой миграцией.

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

Затем отправьте эту последнюю миграцию в рабочую среду и запустите bundle exec rake db:migrate в фоновом режиме.

Я понимаю, что это немного более сложный процесс, но я бы предпочел сделать это, чем иметь проблемы с моей производственной миграцией.

    
28
2013-09-14 02: 01: 38Z
  1. Мне нравится мысль, стоящая за этим, и я хотел бы +1 ваш ответ, но это обновление данных займет очень много времени, так как оно проходит через рельсы и делает одну строку вовремя. Миграция будет выполняться намного быстрее с необработанными инструкциями sql для обновления именованных столбцов. Например, в первом сценарии переноса БД после добавления повторяющихся имен столбцов execute "Update table_name set correct_name_column_one = old_name_column_one"
    2013-09-09 18: 26: 57Z
  2. @ mr.ruh.roh ^ Полностью согласен, должен был написать это в первую очередь. Я отредактировал, чтобы отразить один эффективный оператор SQL. Спасибо за проверку вменяемости.
    2013-09-14 02: 04: 09Z
  3. Что происходит с записями между переходом к новой таблице и обновлением кода для использования новой таблицы? Неужели у вас не осталось потенциально немигрированных данных?
    2014-10-08 15: 59: 19Z
  4. хотя это «безопасный» ответ, я чувствую, что он неполный. Много людейздесь говорят, не делайте этого? постоянство данных. И это действительно. Вероятно, наименее болезненным способом достижения цели является создание новых полей, заполнение их данными из старых столбцов, настройка контроллеров. Если вы хотите удалить старые столбцы, вам, безусловно, придется редактировать представления. Стоимость их хранения - дополнительное место в базе данных и некоторые дублирующие усилия в контроллере. Таким образом, компромиссы очевидны.
    2017-07-29 10: 31: 22Z

Запустите приведенную ниже команду, чтобы создать файл миграции:

rails g migration ChangeHasedPasswordToHashedPassword

Затем в файле, созданном в папке db/migrate, введите rename_column, как показано ниже:

class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
  def change
     rename_column :table_name, :hased_password, :hashed_password
  end
end
    
17
2016-03-03 21: 56: 42Z

Из API:

rename_column(table_name, column_name, new_column_name)

Переименовывает столбец, но сохраняет тип и содержимое остается тем же.

    
14
2014-12-10 13: 01: 24Z

Некоторые версии Ruby on Rails поддерживают метод up /down для миграции, и если у вас есть метод up /down в вашей миграции, то:

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

Если в вашей миграции используется метод change, то:

def change
    rename_column :table_name, :column_old_name, :column_new_name
end

Для получения дополнительной информации вы можете переместить: Ruby on Rails - Миграции или Миграции активной записи . р>     

12
2016-03-03 21: 54: 00Z

Если ваш код не передан другому, то лучше всего сделать rake db:rollback затем измените имя столбца в миграции и rake db:migrate. Вот и все

И вы можете написать еще одну миграцию, чтобы переименовать столбец

 def change
    rename_column :table_name, :old_name, :new_name
  end

Вот и все.

    
11
2013-12-04 14: 34: 30Z
  1. rake db:rollback - отличное предложение. Но, как вы сказали, только если миграция еще не была перенесена.
    2019-03-14 13: 47: 48Z

Если вам нужно поменять имена столбцов, вам нужно создать заполнитель, чтобы избежать ошибки дублированного имени столбца . Вот пример:

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
    
8
2016-08-09 14: 25: 51Z

Если имеющиеся данные не важны для вас, вы можете просто снять исходную миграцию, используя:

rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'

Без кавычек внесите изменения в исходную миграцию и снова запустите миграцию:

rake db:migrate
    
7
2016-03-03 21: 51: 47Z

В качестве альтернативы, если вы не состоите в браке с идеей миграции, для ActiveRecord есть неотразимая жемчужина, которая будет автоматически обрабатывать изменения имени, стиль Datamapper. Все, что вам нужно сделать, это изменить имя столбца в вашей модели (и убедитесь, что вы поместили Model.auto_upgrade! внизу вашего model.rb) и альт! База данных обновляется на лету.

https://github.com/DAddYE/mini_record

Примечание. Чтобы предотвратить конфликты, вам нужно будет использовать db /schema.rb .

Все еще находится на стадии бета-тестирования и, очевидно, не для всех, но все еще является убедительным выбором (в настоящее время я использую его в двух нетривиальных производственных приложениях без проблем)

    
7
2018-02-12 13: 57: 26Z

Просто создайте новую миграцию и в блоке используйте rename_column, как показано ниже.

rename_column :your_table_name, :hased_password, :hashed_password
    
6
2016-03-03 21: 55: 06Z

Для Ruby on Rails 4:

def change
    rename_column :table_name, :column_name_old, :column_name_new
end
    
6
2016-03-03 21: 57: 01Z

Вручную мы можем использовать следующий метод:

Мы можем редактировать миграцию вручную, например:

  • Открыть app/db/migrate/xxxxxxxxx_migration_file.rb

  • Обновление с hased_password до hashed_password

  • Запустите приведенную ниже команду

    $> rake db:migrate:down VERSION=xxxxxxxxx
    

Тогда он удалит вашу миграцию:

$> rake db:migrate:up VERSION=xxxxxxxxx

Это добавит вашу миграцию с обновленным изменением.

    
5
2016-03-03 21: 56: 04Z
  1. это не будет безопасно, так как вы можете потерять данные - если столбец уже активен. но можно сделать для нового столбца и /или таблицы.
    2015-07-23 12: 05: 30Z

Создать файл миграции:

rails g migration FixName

# Создает db /migrate /xxxxxxxxxx.rb

Отредактируйте миграцию, чтобы выполнить свою волю.

class FixName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
    
5
2016-03-03 21: 59: 36Z
$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

Откройте этот файл миграции и измените этот файл, как показано ниже (введите исходный table_name)

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end
    
4
2016-03-23 ​​05: 49: 28Z

Запустите rails g migration ChangesNameInUsers (или как вы хотите его назвать)

Откройте только что созданный файл миграции и добавьте эту строку в метод (между def change и end):

rename_column :table_name, :the_name_you_want_to_change, :the_new_name р>

Сохраните файл и запустите rake db:migrate в консоли

Проверьте свой schema.db, чтобы увидеть, действительно ли имя изменилось в базе данных!

Надеюсь, это поможет:)

    
4
2016-12-23 16: 10: 36Z

Создать миграцию Ruby on Rails :

$:> rails g migration Fixcolumnname

Вставьте код в файл миграции (XXXXXfixcolumnname.rb) :

class Fixcolumnname < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
    
3
2016-03-03 22: 00: 14Z
 def change
    rename_column :table_name, :old_column_name, :new_column_name
  end
    
3
2017-06-08 18: 01: 21Z

Откройте консоль Ruby on Rails и введите:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
    
2
2016-03-03 21: 58: 51Z

У вас есть два способа сделать это:

  1. В этом типе он автоматически запускает обратный код при откате.

    def change
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
  2. Для этого типа он запускает метод up, когда rake db:migrate, и запускает метод down, когда 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
    
2
2016-03-05 05: 10: 58Z

Я нахожусь на рельсах 5.2 и пытаюсь переименовать столбец в пользовательском устройстве.

бит rename_column работал для меня, но единственное число :table_name выдало ошибку «Таблица пользователей не найдена». Множество работало на меня.

rails g RenameAgentinUser

Затем измените файл миграции на этот:

rename_column :users, :agent?, :agent

Где: агент? старое имя столбца.

    
1
2018-09-06 13: 42: 53Z

Давайте KISS . Все это занимает три простых шага. Следующее работает для Rails 5.2 .

1. Создать миграцию

  • rails g migration RenameNameToFullNameInStudents
  • rails g RenameOldFieldToNewFieldInTableName - таким образом, в дальнейшем это будет совершенно понятно сопровождающим базы кода. (используйте множественное число для названия таблицы).

2. Изменить миграцию

# I prefer to explicitly write theupanddownmethods. р>

# ./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

3. Запустите ваши миграции

rake db:migrate р>

И ты в гонках!

    
1
2019-01-22 06: 12: 02Z

Просто сгенерируйте миграцию с помощью команды

rails g migration rename_hased_password

После этого отредактируйте миграцию и добавьте следующую строку в методе изменения

rename_column :table, :hased_password, :hashed_password

Это должно сработать.

    
0
2017-10-05 12: 02: 57Z

Изменения в Rails 5

например:

  

рельсы g модель Студент имя_участника: возраст строки: целое число

если вы хотите изменить имя студента на имя

Примечание: - если вы не запускаете rails db: migrate

Вы можете выполнить следующие шаги

  

рельсы d модель Студент имя_ ученика: возраст строки: целое число

Это удалит сгенерированный файл миграции, теперь вы можете исправить имя столбца

  

рельсы g модель Имя ученика: возраст строки: целое число

Если вы мигрировали (rails db: migrate), следующие опции для изменения имени столбца

  

рельсы и миграция RemoveStudentNameFromStudent имя_студента: строка

     

рельсы и миграция Имя AddNameToStudent: строка

    
0
2017-12-20 12: 08: 30Z
  1. Разве это не должно быть: rails g migration RemoveStudentNameFromStudentS student_name:string (студенты во множественном числе)?
    2019-01-14 04: 38: 57Z
  2. Также это опасно: столбец не переименовывается, но полностью удаляется и затем читается. Что будет с данными? Это может быть не тем, что хочет пользователь.
    2019-01-14 04: 45: 52Z

Обновление . Близким родственником create_table является change_table, используемый для изменения существующих таблиц. Он используется аналогично create_table, но объект, переданный блоку, знает больше хитростей. Например:

class ChangeBadColumnNames < ActiveRecord::Migration
  def change
    change_table :your_table_name do |t|
      t.rename :old_column_name, :new_column_name
    end
  end
end

Этот способ более эффективен, если мы используем другие методы изменения, такие как: удалить /добавить индекс /удалить индекс /добавить столбец, например, мы можем сделать следующее:

# 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
#...
    
- 1
2016-05-21 05: 32: 00Z
источник размещен Вот