Міграція рейки DB - Як видалити таблицю?


507

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

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

Я спробував:

rails generate migration drop_tablename

але це просто породило порожню міграцію.

Який "офіційний" спосіб опустити стіл в Rails?


1
Оскільки rails generate migrationє параметри командного рядка для генерації коду міграції для створення таблиць, додавання чи зміни стовпців тощо, було б непогано, якби у нього також був варіант для випадання таблиці - але це не так. Звичайно, написання upчастини просто - просто зателефонувати drop_table- але downчастина, генеруючи таблицю знову, може бути не завжди такою простою, особливо якщо схема міграції відповідної таблиці була змінена міграціями після її початкового створення. Можливо, хтось повинен запропонувати розробникам Rails, що додавання такої опції було б гарною ідеєю.
Teemu Leisti

3
@TeemuLeisti Як щодо просто скопіювати та вставити поточне визначення таблиці з schema.rb? Я роблю це таким чином весь час ...
jasoares

1
@ Жоао Соарес: ​​Гаразд, я думаю, це працює. Однак було б непогано, якби процес міг бути автоматизований, щоб ви могли просто дати rakeкоманду створення міграції з назвою таблиці в якості параметра, яка б створювала необхідні upта downфункції.
Teemu Leisti

Відповіді:


647

Ви не завжди зможете просто генерувати міграцію, щоб вже мати потрібний код. Ви можете створити порожню міграцію, а потім заповнити її потрібним кодом.

Ви можете знайти інформацію про те, як виконати різні завдання з міграції тут:

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

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

drop_table :table_name

3
Це працювало і для мене. Але після повної міграції (встановлення з нуля) тепер буде створена таблиця, а потім знову знижена. Чи безпечно видалити міграцію та відпустити міграцію вниз?
berkes

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.
Себастіалонсо

4
Видалення таблиці видаляє всі дані, якщо ви відтворите їх у downметоді, ви не відновите їх, так що насправді це не правильний відкат. Краще чітко вказати, що міграція незворотна, ніж дати помилкове відчуття, з якого її можна відновити.
vivi

314

Запишіть міграцію вручну. Наприклад, пробіг rails g migration DropUsers.

Щодо коду міграції, я просто навожу цитату Максвелла Холдера за повідомленням « Мітки міграції рейлів»

БАД - працює 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 console

Потім просто введіть:

ActiveRecord::Migration.drop_table(:table_name)

І зробили, працювали для мене!


Модель залишається там, поки не запуститеrails destroy model User
gm2008

2
Запускайте це, лише якщо хочете назавжди позбутися від столу. Рейки не будуть знати про це падіння. Міграція порушується після запуску цієї команди. Не вдається СТВОРИТИСЯ, ЗНАТИ ... ETC. ПОМИЛКА SQLite3 :: SQLException: немає такої таблиці: накопичення: СРОК ТАБЛИЦІ "sometable"
zee

36

Вам потрібно створити новий файл міграції за допомогою наступної команди

rails generate migration drop_table_xyz

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

drop_table :tablename

Або якщо ви хотіли скинути стіл без міграції, просто відкрийте консоль рейки

$ rails c

і виконати наступну команду

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

або ви можете використовувати більш спрощену команду

ActiveRecord::Migration.drop_table(:table_name)

21
  1. рейки g міграція drop_users
  2. редагувати міграцію
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. rake db: мігрувати

13

Думаю, щоб бути повністю "офіційним", вам потрібно створити нову міграцію та поставити drop_table у self.up. Тоді метод self.down повинен містити весь код для відтворення таблиці повністю. Імовірно, що код можна було просто взяти з schema.rb під час створення міграції.

Здається трохи дивним: вводити код, щоб створити таблицю, яку ви знаєте, що вам більше не потрібно, але це дозволить зберегти весь код міграції повним та "офіційним", правда?

Я просто зробив це для столу, який мені потрібно було скинути, але, чесно кажучи, не перевіряв "вниз" і не знаю, чому б це зробити.


1
Дивно, але схоже, що мені теж доведеться це робити.
digitalWestie

7
Або ви можете просто скористатися: raise ActiveRecord::IrreversibleMigrationу методі self.down, тож у ЛІСЬКОМ ви повідомляєте про помилку / повідомлення, якщо ви коли-небудь намагатиметесь відкатати.
Стеф Роуз

1
Я б протестував тестування лише тому, що в іншому випадку я ввожу неперевірений код у свій проект. Як я можу повторно використовувати оригінальний метод міграції? Я спробував, CreateMyTable.upі ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)де X - це міграція, яка спочатку створила таблицю, але не працює - в обох підходах AR спочатку перевіряє, чи була вже застосована міграція, і мовчки пропускає її, якщо вона є. `
Ісаак Бетеш

12

ви можете просто скинути стіл з рейки консолі. спочатку відкрийте консоль

$ rails c

потім вставте цю команду в консоль

ActiveRecord::Migration.drop_table(: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

8

Мені не вдалося змусити його працювати зі сценарієм міграції, тому я продовжив це рішення. Введіть консоль рейки за допомогою терміналу:

rails c

Тип

ActiveRecord::Migration.drop_table(:tablename)

Це добре працює для мене. Це видалить попередню таблицю. Не забувайте бігати

rails db:migrate



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

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

Не забудьте видалити файл міграції та структуру таблиці зі схеми


Ви також можете відкрити його, ввівши простоrails db
ARK

0

якщо ви хочете опустити певну таблицю, ви можете це зробити

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

в іншому випадку, якщо ви хочете скинути всю свою базу даних, яку можете зробити

$rails db:drop

-1

Таблиця випаду / міграція

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

Додавання простої відповіді не заслуговує на те, щоби її зняти. Це все ще актуально, я думаю. Будьте ласкаві до нових користувачів, будь ласка.
ARK

-2

Якщо ви хочете видалити таблицю зі схеми, виконайте нижче операцію -

rails db:rollback
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.