Миграция БД Rails - Как удалить таблицу?

507

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

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

Я пробовал:

rails generate migration drop_tablename

но это только породило пустую миграцию.

Каков «официальный» способ удаления таблицы в Rails?

Джейсон Уайтхорн
источник
1
Поскольку в rails generate migrationкомандной строке есть параметры для генерации кода миграции для создания таблиц, добавления или изменения столбцов и т. Д., Было бы неплохо, если бы у него также была возможность удаления таблицы, но это не так. Конечно, написание upчасти простое - просто вызов drop_table- но downчасть, генерирующая таблицу снова, не всегда может быть такой простой, особенно если схема рассматриваемой таблицы была изменена миграциями после ее первоначального создания. Может быть, кто-то должен предложить разработчикам Rails, что добавление такой опции было бы хорошей идеей.
Теему Лейсти
3
@TeemuLeisti Как насчет просто скопировать и вставить текущее определение таблицы из schema.rb? Я делаю так все время ...
Jasoares
1
@ Жоао Соареш: ОК, думаю, это работает. Однако было бы неплохо, если бы этот процесс можно было автоматизировать, чтобы вы могли просто дать rakeкоманду создания миграции с именем таблицы в качестве параметра, которая выдаст необходимые функции upи downфункции.
Теему Лейсти

Ответы:

647

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

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

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

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

drop_table :table_name
Пит
источник
3
Это сработало и для меня. Но при полной миграции (установка с нуля) таблица будет сначала создана, а затем снова удалена. Безопасно ли удалять и создавать миграции в будущем?
Беркес
2
Любое представление здесь о том, лучше ли отбросить таблицы или вернуться к предыдущей схеме базы данных?
Уильям скажет
3
Если вы закончили со столом и больше не планируете его использовать, я бы сказал, просто бросьте его. Лучше избавиться от него, если он не используется.
Пит
6
Ответ @BederAcostaBorges более понятен и точен
onerinas
2
Как также удалить все внешние ключи? В других таблицах есть столбцы, указывающие на удаляемую таблицу.
Мартин Коничек
352

Сначала создайте пустую миграцию с любым именем, которое хотите. Это важно сделать так, потому что это создает соответствующую дату.

rails generate migration DropProductsTable

Это создаст файл .rb в / db / migrate / like 20111015185025_drop_products_table.rb

Теперь отредактируйте этот файл так:

class DropProductsTable < ActiveRecord::Migration
  def up
    drop_table :products
  end

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

Единственное, что я добавил, было drop_table :productsи raise ActiveRecord::IrreversibleMigration.

Тогда беги, rake db:migrateи он уронит тебе стол.

Брэндон О'Рурк
источник
14
Для воссоздания удаляемой таблицы следует использовать миграцию вниз.
fflyer05
1
Эта миграция никогда не может быть отменена, даже в процессе разработки. Не лучше ли оставить пустую миграцию пустой?
mhriess
1
Это лучший ответ + комментарий fflyer
Зак Шапиро
2
@mjnissim и fflyer05 верны, чтобы избежать каких-либо странностей, вы должны воссоздать таблицу в методе down.
Себастьянсо
5
Удаление таблицы удаляет все данные, если вы воссоздаете их в downметоде, вы не будете восстанавливать их, поэтому это не будет правильным откатом. Лучше четко указать, что миграция необратима, чем дать ложное представление о том, что ее можно восстановить.
Виви
314

Напишите вашу миграцию вручную. Например, бегиrails g migration DropUsers .

Что касается кода миграции, я просто процитирую пост Максвелла Холдера Rails Migration Checklist

ПЛОХО - работает, rake db:migrateа затем rake db:rollbackне получится

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users
  end
end

ХОРОШО - показывает намерение, что миграция не должна быть обратимой

class DropUsers < ActiveRecord::Migration
  def up
    drop_table :users
  end

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

ЛУЧШЕ - на самом деле обратимо

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users do |t|
      t.string :email, null: false
      t.timestamps null: false
    end
  end
end
Бедер Акоста Борхес
источник
Если вы вырезаете и вставляете в блок из schema.rb, не забудьте также искать schema.rbвнешние ключи. Затем добавьте определение внешнего ключа в drop_tableблок, например:t.foreign_key "other_table"
Ленчо Рейес
197

Хотя ответы, представленные здесь, работают правильно, я хотел что-то более «простое», но нашел это здесь: ссылка Сначала введите консоль rails:

$rails console

Затем просто введите:

ActiveRecord::Migration.drop_table(:table_name)

И сделано, работал для меня!

lllllll
источник
Модель все еще там, пока вы не запуститеrails destroy model User
gm2008
2
Запускайте это, только если вы хотите избавиться от таблицы навсегда. Rails не будет знать об этом падении. Миграция не работает после запуска этой команды. НЕ МОЖЕТ СОЗДАТЬ, УБРАТЬ ... И Т.Д. ОШИБКА SQLite3 :: SQLException: нет такой таблицы: начисления: DROP TABLE "sometable"
zee
36

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

rails generate migration drop_table_xyz

и напишите код drop_table во вновь созданном файле миграции (db /igration / xxxxxxx_drop_table_xyz), например

drop_table :tablename

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

$ rails c

и выполните следующую команду

ActiveRecord::Base.connection.execute("drop table table_name")

или вы можете использовать более упрощенную команду

ActiveRecord::Migration.drop_table(:table_name)
Шахзад Тарик
источник
21
  1. рельсы г миграции drop_users
  2. редактировать миграцию
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. грабли дБ: мигрировать
Аашиш Сайни
источник
13

Я думаю, чтобы быть полностью «официальным», вам нужно создать новую миграцию и поместить drop_table в self.up. Затем метод self.down должен содержать весь код для полного воссоздания таблицы. Предположительно, этот код можно было просто взять из schema.rb во время создания миграции.

Кажется немного странным, вставлять код для создания таблицы, которая, как вы знаете, вам больше не понадобится, но при этом весь код миграции будет полным и «официальным», верно?

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

Фрэнсис Поттер
источник
1
Странно, но, похоже, мне тоже придется это сделать.
digitalWestie
7
Или вы можете просто использовать: raise ActiveRecord::IrreversibleMigrationв методе self.down, чтобы вы в LEAST выдавали ошибку / уведомление, если вы когда-нибудь попытаетесь откатиться.
Стеф Роуз,
1
Я бы протестировал даун только потому, что в противном случае я внедряю непроверенный код в свой проект. Как я могу использовать метод up оригинальной миграции? Я пробовал, CreateMyTable.upи ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)где X - это миграция, которая первоначально создала таблицу, но ни один из них не работает - в обоих подходах AR сначала проверяет, была ли миграция уже применена, и молча пропускает ее, если она есть. `
Исаак Бетеш
12

Вы можете просто уронить стол с консоли рельсов. сначала откройте консоль

$ rails c

затем вставьте эту команду в консоль

ActiveRecord::Migration.drop_table(:table_name)

замените table_name на таблицу, которую вы хотите удалить.

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

$ rails runner "Util::Table.clobber 'table_name'"
Фарзпал Сингх
источник
10

Простой и официальный способ будет следующим:

  rails g migration drop_tablename

Теперь перейдите к вашей db / migrate и найдите свой файл, который содержит имя_папки в качестве имени файла, и отредактируйте его так.

    def change
      drop_table :table_name
    end

Тогда вам нужно бежать

    rake db:migrate 

на вашей консоли.

Махеш Места
источник
9

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

http://guides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations

Генерация миграции:

rails generate migration revert_create_tablename

Напишите миграцию:

require_relative '20121212123456_create_tablename'

class RevertCreateTablename < ActiveRecord::Migration[5.0]
  def change
    revert CreateTablename    
  end
end

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

Матеус Сильва
источник
8

Альтернатива повышению исключений или попытке воссоздать пустую таблицу - при этом разрешая откат миграции, повтор и т. Д. -

def change
  drop_table(:users, force: true) if ActiveRecord::Base.connection.tables.include?('users')
end
aqwan
источник
8

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

rails c

Тип

ActiveRecord::Migration.drop_table(:tablename)

Это хорошо работает для меня. Это удалит предыдущую таблицу. Не забудь бежать

rails db:migrate
Срикант V
источник
7

Откройте консоль

ActiveRecord::Base.connection.execute("drop table table_name")
Manish Nautiyal
источник
4

ActiveRecord::Base.connection.drop_table :table_name

nhegroj
источник
2

Мне нужно было удалить наши сценарии миграции вместе с самими таблицами ...

class Util::Table < ActiveRecord::Migration

 def self.clobber(table_name)   
    # drop the table
    if ActiveRecord::Base.connection.table_exists? table_name
      puts "\n== " + table_name.upcase.cyan + " ! " 
           << Time.now.strftime("%H:%M:%S").yellow
      drop_table table_name 
    end

    # locate any existing migrations for a table and delete them
    base_folder = File.join(Rails.root.to_s, 'db', 'migrate')
    Dir[File.join(base_folder, '**', '*.rb')].each do |file|
      if file =~ /create_#{table_name}.rb/
        puts "== deleting migration: " + file.cyan + " ! "
             << Time.now.strftime("%H:%M:%S").yellow
        FileUtils.rm_rf(file)
        break
      end
    end
  end

  def self.clobber_all
    # delete every table in the db, along with every corresponding migration 
    ActiveRecord::Base.connection.tables.each {|t| clobber t}
  end

end

из окна терминала запустить:

$ rails runner "Util::Table.clobber 'your_table_name'"

или

$ rails runner "Util::Table.clobber_all"
Аарон Хендерсон
источник
1

лучший способ сделать это

rails g migration Drop_table_Users

затем сделайте следующее

rake db:migrate
Anoob K Bava
источник
1

Запустить

rake db:migrate:down VERSION=<version>

куда <version> номер версии вашего файла миграции, который вы хотите вернуть.

Пример:-

rake db:migrate:down VERSION=3846656238
Рангит Ранджан
источник
1

если кто-то ищет, как это сделать в SQL.

тип rails dbconsoleс терминала

введите пароль

В консоли сделать

USE db_name;

DROP TABLE table_name;

exit

Пожалуйста, не забудьте удалить файл миграции и структуру таблицы из схемы

Shan
источник
Вы также можете открыть его, просто набравrails db
ARK
0

если вы хотите удалить конкретную таблицу, вы можете сделать

$ rails db:migrate:up VERSION=[Here you can insert timestamp of table]

в противном случае, если вы хотите удалить всю свою базу данных, вы можете сделать

$rails db:drop
Nicollas
источник
-1

Drop Table / Migration

run: - $ rails генерирует миграцию DropTablename

exp: - $ rails генерирует миграцию DropProducts

Панкадж Дхоте
источник
-1

Запустите эту команду: -

rails g migration drop_table_name

тогда:

rake db:migrate

или если вы используете базу данных MySql, то:

  1. войти с базой данных
  2. show databases;
  3. show tables;
  4. drop table_name;
Нитин Ракеш
источник
3
Добавляет ли этот ответ что-либо к существующему, принятому ответу? Если нет, нет необходимости размещать это.
Том Лорд
1
это создает пустую миграцию в рельсах 4.2, как уже говорилось в самом вопросе.
Bert Bruynooghe
Это именно то, что ОП изначально пытался ... этот ответ должен быть удален
webaholik
Добавление простого ответа не заслуживает отрицательного ответа. Это все еще актуально, я думаю. Будьте добры к новым пользователям, пожалуйста.
АРК
-2

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

rails db:rollback
iamnair
источник