【发布时间】:2012-10-21 20:04:20
【问题描述】:
我有这个测试数据库,到现在为止,里面塞满了垃圾。现在我在 Rails 控制台中完成了一些 Table.destroy_all 命令,它删除了所有记录和依赖项,这很棒。然而;我想截断所有内容,以便 ID 等再次从 1 开始。 Rails 3有什么办法吗?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3 truncate rails-console
我有这个测试数据库,到现在为止,里面塞满了垃圾。现在我在 Rails 控制台中完成了一些 Table.destroy_all 命令,它删除了所有记录和依赖项,这很棒。然而;我想截断所有内容,以便 ID 等再次从 1 开始。 Rails 3有什么办法吗?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3 truncate rails-console
只需在下一次测试运行时重建数据库(这将在删除后自动发生)。
rake db:drop RAILS_ENV=test
【讨论】:
仅当您需要重新创建整个数据库时,接受的答案才有效。
删除单个表(带有回调)并让 ID 从 1 开始:
Model.destroy_all # Only necessary if you want to trigger callbacks.
ActiveRecord::Base.connection.execute("TRUNCATE #{table_name} RESTART IDENTITY")
如果您使用的是 Sqlite,它不支持截断,请执行以下操作:
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}'")
【讨论】:
ActiveRecord::Base.connection.execute("TRUNCATE #{table_name}") 对于 PostgreSQL:ActiveRecord::Base.connection.execute("TRUNCATE #{table_name} RESTART IDENTITY")
你也可以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,所有表都将从我的 TEST 数据库中删除,如果我删除 RAILS_ENV=test,那么所有 ENVIRONNMENT(生产、测试、开发)表都将被删除,它还会从它的 db/shema.rb 文件中清除迁移数据。
【讨论】:
rake db:reset 将执行rake db:drop db:setup。换句话说,删除数据库并重新设置数据库。
【讨论】:
(聚会有点晚了,我知道)
在控制台中要求这样做:
2.1.2 :001 > Post.all.each do |post|
2.1.2 :002 > post.destroy!
2.1.2 :003 > end
同样有效...
这实质上是遍历所有帖子并销毁它们。虽然它不会改变你的自动增量值......
同样的逻辑也适用于 Rails 3(尽管我使用的是 Rails 4)
【讨论】:
each,使用find_each。它确保您不会在一次查询中获得十亿条记录 2. 如果您只需要从数据库中删除记录(不运行任何回调),请不要使用循环。就做Post.delete_all
这对我有用 -
ActiveRecord::Base.connection.execute("TRUNCATE table_name")
【讨论】:
假设您使用的是 MySQL 或 Postgre 而不是 SQlite3(不支持 TRUNCATE),您可以执行以下操作:
MyModel.connection_pool.with_connection { |c| c.truncate(MyModel.table_name) }
请注意,这不会调用 ActiveRecord 回调。
【讨论】:
Model.connection.truncate(Model.table_name)
【讨论】:
我使用下面的代码来截断所有表格
ActiveRecord::Base.establish_connection
ActiveRecord::Base.connection.tables.each do |table|
next if table == 'schema_migrations'
case ActiveRecord::Base.connection.adapter_name.downcase.to_sym
when :mysql2 , :postgresql
ActiveRecord::Base.connection.execute("TRUNCATE #{table}")
ActiveRecord::Base.connection.execute("TRUNCATE #{table} RESTART IDENTITY")
when :sqlite
ActiveRecord::Base.connection.execute("DELETE FROM #{table}")
end
end
【讨论】:
Rails 6.0+ 添加新方法:truncate_tables
ActiveRecord::Base.connection.truncate_tables([:table1_name, :table2_name])
【讨论】: