Does rename_column заботится об индексах? - программирование
Подтвердить что ты не робот

Does rename_column заботится об индексах?

Скажем, у нас есть что-то вроде этого:

add_column :users, :single, :boolean
add_index :users, :single

а затем мы будем делать

rename_column :users, :single, :married

Будет ли ActiveRecord и/или база данных обрабатывать переименование индекса, или мне нужно вручную сбросить индекс и добавить его снова?

4b9b3361

Ответ 1

Для PostgreSQL rename_column реализуется как простой ALTER TABLE ... RENAME COLUMN ... и сохраняет индексы.

Версии MySQL (оба из них) выполняют ALTER TABLE ... CHANGE ... и также сохраняют индексы.

Предполагается, что версия SQLite скопирует всю таблицу (с индексами), отбросит старую, а затем скопирует копию обратно в исходное имя таблицы. Кажется, что копирование обрабатывает переименование столбца при копировании индексов:

def copy_table(from, to, options = {})
  #...
  copy_table_indexes(from, to, options[:rename] || {})

и внутри copy_table_indexes:

columns = index.columns.map {|c| rename[c] || c }.select do |column|
  to_column_names.include?(column)
end

Итак, стандартные драйверы сохранят ваши индексы, когда вы выполняете rename_column, и драйвер SQLite прилагает определенные усилия для этого.

В документации API не указано какое-либо конкретное поведение, хотя другие драйверы могут делать другие вещи. Ближайшая документация приходит к тому, чтобы говорить что-либо об индексах, это в active_record/migration.rb:

rename_column(table_name, column_name, new_column_name): Переименовывает столбец, но сохраняет тип и содержимое.

Я думаю, что любой драйвер сохранит индексы, но нет гарантии; писатель-водитель, безусловно, будет глупо не сохранять индексы.

Это не окончательный или авторитетный ответ, но ваши индексы должны быть сохранены, если вы используете стандартные PostgreSQL, MySQL (либо один из них), либо драйверы SQLite.


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

Приведенное выше поведение изменено в Rails 4:

  • В Rails 4.0 при переименовании столбца или таблицы соответствующие индексы также переименовываются. Если у вас есть миграции, которые переименовывают индексы, они больше не нужны.

Таким образом, ActiveRecord автоматически переименует индексы, чтобы соответствовать новым именам таблиц или столбцов при переименовании таблицы или столбца. Спасибо sequielo за хедз-ап.