使用Rails控制台截断表格(或表格)

61

我有一个测试数据库,现在里面充满了垃圾数据。我已经在Rails控制台中执行了一些Table.destroy_all命令,删除了所有记录和依赖关系,这很棒。但是,我想要截断所有内容,使ID等重新从1开始。在Rails 3中有没有这样的方法?

12个回答

162

如果您需要重新创建整个数据库,则接受的答案有效。
要丢弃单个表(带有回调)并使ID从1开始:

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

如果你正在使用Sqlite,它不支持truncate,所以请按照以下步骤操作:

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
当一个表需要被截断时,你的答案是正确的(我感谢你)。我选择了Yam Marcovic的答案作为采纳的答案,因为我确实要求“所有内容”都要被截断。 - CaptainCarl
4
谢谢您的投票。从问题中并不能清楚地看出整个数据库的要求!只是提供一些信息,运行rake db:drop命令将删除数据库。如果要求只是截断所有表,您可以运行ActiveRecord::Base.connection.tables.collect{|table_name| ActiveRecord::Base.connection.execute("TRUNCATE #{table_name}")}。虽然它可能无法处理回调,但我想这不是必要的,因为我们正在截断所有表。 - Ravi Sankar Raju
destroy_all会调用每个记录的destroy方法,这与截断表格非常不同。从文档中可以看到:#通过实例化每个记录并调用其destroy方法来销毁与+conditions+匹配的记录。将执行每个对象的回调(包括<tt>:dependent</tt>关联选项和+before_destroy+/+after_destroy+观察者方法)。返回已删除的对象集合;每个对象都将被冻结,以反映不应进行任何更改(因为它们无法持久化)。 - justingordon
4
在Postgres中,第二个命令实际上并没有重置ID列的自增值。要想实现这一点,你需要使用"TRUNCATE table_name RESTART IDENTITY"命令。请参考https://dev59.com/9msz5IYBdhLWcg3w3rwJ#7610991。 - Doug Johnston
5
仅供澄清: 对于MySQL/MariaDB: ActiveRecord::Base.connection.execute("TRUNCATE #{table_name}") 对于PostgreSQL: ActiveRecord::Base.connection.execute("TRUNCATE #{table_name} RESTART IDENTITY") - Sergio Gonzalez
引用表名:c = ActiveRecord::Base.connection; c.execute("TRUNCATE #{c.quote_table_name(Model.table_name)}")。必要时添加 RESTART IDENTITY/CASCADE - x-yuri

30
Model.connection.truncate(Model.table_name)

自Rails 4.2.1以来 - sunki

18

这个方法对我管用 - ActiveRecord::Base.connection.execute("TRUNCATE table_name")


2
但是最好和最简单的答案 - Anton Semenichenko

8

我认为应该是 ActiveRecord::Base.connection.truncate_tables(*[:table1_name, :table2_name]) 或者 ActiveRecord::Base.connection.truncate_tables(:table1_name, :table2_name) - new2cpp

2
假设您正在使用MySQL或Postgre而不是不支持TRUNCATE的SQlite3,您可以执行以下操作:
MyModel.connection_pool.with_connection { |c| c.truncate(MyModel.table_name) }

请注意,这不会触发ActiveRecord回调。

2
你可以运行rake db:rollback STEP=3 RAILS_ENV=test命令。其中的3代表你在db/migrate目录下有多少个迁移文件。举个例子:如果我有三个迁移文件,那么这个命令会回滚最近的三个迁移。
db/migrate
20140121065542_create_users.rb
20140121065710_create_profiles.rb
20140121065757_create_articles.rb
20140121065900_create_comments.rb
20140121065929_create_categories.rb

我总共有5个迁移需要删除。如果我运行 rake db:rollback STEP=5 RAILS_ENV=test,所有表格都将从我的测试数据库中删除。如果我去掉RAILS_ENV=test,那么所有环境(生产、测试、开发)的表格都将被删除,并且它还会清除db/schema.rb文件中的迁移数据。


2

rake db:reset命令将执行rake db:drop db:setup命令。换句话说,它会删除数据库并重新设置数据库。

原文链接


通过这样做,我们将会丢失重要的数据,强烈不建议。 - Muhammad Sannan Khalid
原始问题是关于如何删除数据库中的所有数据。 - jwadsack
1
原始问题标题为“使用Rails控制台截断表”,重置整个数据库可能不是所需的。 - dancow

2

只需在下一次测试运行时重新构建数据库(在删除数据库后,这将自动发生)。

rake db:drop RAILS_ENV=test


0

您可以在 Rails 控制台中使用 ModelName.delete_all


0
Rails 6 新增了 rake 任务 db:truncate_all。请参阅 文档
您可以在 Rails 控制台中调用它:
ActiveRecord::Tasks::DatabaseTasks.truncate_all

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接