检查Rails中是否存在表


174

我有一个rake任务,除非存在一个表,否则该任务将无法工作。我正在与一个网站上的20多位工程师合作,因此我想确保他们已经迁移了表,然后他们才能执行瑞克任务,该任务将填充相应的表。

AR是否有诸如此类的方法Table.exists?如何确保他们已成功迁移表?


12
开玩笑吧..迁移表需要多少工程师:)
Zabba 2011年

1
在生产中1.在暂存中分别进行数十次和多次。
thenengah

2
在您的rake任务开始时运行迁移会更容易吗?因此,您不必担心缺少表。
raskhadafi 2012年

@raskhadafi:请注意,如果您的配置/初始化程序使用缺少的表,将会给您带来问题。(即,甚至rake db:migrate会失败。)
ocodo

Answers:


302

在Rails 5中,API对于表/视图(统称为数据源)变得明确

# Tables and views
ActiveRecord::Base.connection.data_sources
ActiveRecord::Base.connection.data_source_exists? 'kittens'

# Tables
ActiveRecord::Base.connection.tables
ActiveRecord::Base.connection.table_exists? 'kittens'

# Views
ActiveRecord::Base.connection.views
ActiveRecord::Base.connection.view_exists? 'kittens'

在Rails 2、3和4中,API是关于table的

# Listing of all tables and views
ActiveRecord::Base.connection.tables

# Checks for existence of kittens table/view (Kitten model)
ActiveRecord::Base.connection.table_exists? 'kittens'

获取迁移状态:

# Tells you all migrations run
ActiveRecord::Migrator.get_all_versions

# Tells you the current schema version
ActiveRecord::Migrator.current_version

如果您需要更多用于迁移或元数据的API,请参见:


4
ActiveRecord::Base.connection.table_exist 'users'将检查用户表。
thenengah

4
ActiveRecord::Base.connection.table_exists? 'kittens会检查小猫桌子。除非我销毁了所有小猫!drop_table :kittens
thenengah

1
多谢你们!我刚刚使用过.index_exists?('kittens', 'paws')
旅行

14
这适用于ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Greg,

1
ActiveRecord::Base.connection.data_source_exists? 'table_name'现在是正确的了
Dorian

57

即使表不存在:

型号Kitten,预期工作台kittens 滑轨3:

Kitten.table_exists?#=>错误


+ 1更优雅的解决方案。如果模型覆盖表名,则也适用。
Daniel Rikowski

1
确认适用于Rails 2.3.18-lts(已测试一张表,运行脚本/控制台前缺少一张表)
iheggie 2014年

32

我在尝试通过迁移删除表时发现了这一点:

drop_table :kittens if (table_exists? :kittens)
ActiveRecord::Migration.drop_table :kittens if (ActiveRecord::Base.connection.table_exists? :kittens)

适用于Rails 3.2

这种更简单的形式将在Rails 5中提供:

drop_table :kittens, if_exists: true

参考:https : //github.com/rails/rails/pull/16366

这是Rails 5 ActiveRecord的CHANGELOG

介绍drop_table的:if_exists选项。

例:

drop_table(:posts, if_exists: true)

那将执行:

DROP TABLE IF EXISTS posts

如果表不存在,则if_exists:false(默认值)会引发异常,而if_exists:true则不执行任何操作。


如果该表实际上是视图,则该操作将失败,因为该表似乎已存在,但是DROP TABLE无法删除它。
mcr

8

Rails 5.1

if ActiveRecord::Base.connection.data_source_exists? 'table_name'
   drop_table :table_name
end

要么

drop_table :table_name, if_exists: true

2
table_exists仍在rails-5中工作,但其行为将更改为仅检查表。从5.0.1版本开始,它检查视图和表。data_source_exists保持该行为,而table_exists将更改为仅检查表。
约翰·内格勒

他不是要检查迁移表,而是需要确保该表存在于瑞克任务上
Juan Furattini

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.