2012-11-01 10 views
30

Mam tę bazę testową, która jest już wypełniona śmieciami. Teraz zrobiłem kilka poleceń Table.destroy_all w konsoli rails, która usuwa wszystkie rekordy i zależności, co jest niesamowite. Jednak; Chciałbym obciąć wszystko, aby identyfikatory itp. Zaczęły się od 1 ponownie. Czy jest jakiś sposób w Rails 3?Stoły ścięte z konsolami szynowymi

Odpowiedz

104

Przyjęte rozwiązanie działa tylko wtedy, gdy trzeba odtworzyć całą bazę danych.
Aby usunąć pojedynczy tabeli (z wywołania zwrotne) i uzyskać identyfikatory zacząć od 1:

Model.destroy_all # Only necessary if you want to trigger callbacks. 
ActiveRecord::Base.connection.execute("TRUNCATE #{table_name} RESTART IDENTITY") 

Jeśli używasz SQLite, że nie obsługuje obciąć tak, wykonaj następujące czynności:

Model.destroy_all # Only necessary if you want to trigger callbacks. 
ActiveRecord::Base.connection.execute("Delete from #{table_name}") 
ActiveRecord::Base.connection.execute("DELETE FROM SQLITE_SEQUENCE WHERE name='#{table_name}'") 
+2

Twoja odpowiedź jest poprawna, gdy jedna tabela powinna zostać obcięta (i dziękuję za to) Wybrałam odpowiedź Yam Marcovica jako zaakceptowaną odpowiedź, ponieważ poprosiłam o "wszystko", aby ją skrócić. – CaptainCarl

+4

Dzięki za głosowanie. Całe wymaganie db nie było jasne z pytania!Tylko dla informacji, rake db: drop spowoduje usunięcie bazy danych. Jeśli wymagane jest po prostu obcięcie wszystkich tabel, możesz uruchomić ActiveRecord :: Base.connection.tables.collect {| table_name | ActiveRecord :: Base.connection.execute ("TRUNCATE # {table_name}"}}. Chociaż może nie dbać o wywołania zwrotne, nie jest to konieczne, ponieważ obcinamy wszystkie tabele. –

+0

destroy_all wywoła destru w każdym rekordzie, co jest zupełnie inne niż obcięcie tabeli. From Docs: # Niszczy rekordy dopasowania + warunki + poprzez utworzenie każdego rekordu # i wywołanie jego metody + destroy +. Połączenia zwrotne każdego obiektu są wykonywane (w tym : zależne opcje skojarzeń i # + metody before_destroy +/+ after_destroy + Observer). Zwraca kolekcję obiektów, które zostały zniszczone; każda z nich zostanie zamrożona, aby # odzwierciedlać, że nie należy wprowadzać żadnych zmian (ponieważ nie mogą one być oznaczone jako nieprzetworzone). – justingordon

3

Po prostu przebuduj bazę danych w następnym uruchomieniu testowym (nastąpi to automatycznie po jej upuszczeniu).

rake db:drop RAILS_ENV=test

3

Można również wykonać: rake db:rollback STEP=3 RAILS_ENV=test

gdzie 3 oznacza liczbę migracji w db/migrate. Na przykład: Jeśli mam w

db/migrate 
20140121065542_create_users.rb 
20140121065710_create_profiles.rb 
20140121065757_create_articles.rb 
20140121065900_create_comments.rb 
20140121065929_create_categories.rb 

Więc mam 5 migracje w sumie do usunięcia. Jeśli wykonam rake db:rollback STEP=5 RAILS_ENV=test wszystkie tabele zostaną usunięte z mojej bazy danych TEST i jeśli usuniemy RAILS_ENV = test, to wszystkie tabele ENVIRONNMENT (produkcja, test, rozwój) zostaną usunięte i wyczyści również plik db/shema.rb z jego danych migracji .

2

rake db:reset wykona rake db:drop db:setup. Innymi słowy, upuść bazę danych i ponownie skonfiguruj bazę danych.

Source

+0

w ten sposób tracimy ważne dane, wysoce niezalecane. –

0

(trochę późno do partii, wiem)

wyjściowa to zrobić w konsoli:

2.1.2 :001 > Post.all.each do |post| 
2.1.2 :002 > post.destroy! 
2.1.2 :003 > end 

działa tak dobrze ...

ten zasadniczo pętle przez wszystkie posty i niszczy je. Nie zmienia swoją wartość automatycznego przyrostu chociaż ...

sama logika powinna pracować dla szyny 3, a także (choć używam Rails 4)

+2

1. Nie używaj 'each', użyj' find_each'. Zapewnia, że ​​nie dostaniesz miliarda rekordów w jednym zapytaniu. 2. Nie używaj pętli, jeśli chcesz po prostu usunąć rekordy z DB (bez uruchamiania żadnych połączeń zwrotnych). Po prostu wykonaj 'Post.delete_all' – Kukunin

4

ten pracował dla mnie >>> ActiveRecord :: Base. connection.execute ("TRUNCATE nazwa_tabeli")

1

Zakładając, że używasz MySQL lub Postgre a nie sqlite3 (który nie obsługuje TRUNCATE), można wykonać następujące czynności:

MyModel.connection_pool.with_connection { |c| c.truncate(MyModel.table_name) } 

pamiętać, że to będzie nie wywoływać ActiveRec wezwania zwrotne.

Powiązane problemy