[英]SQLite migration removes 'add_index' and 'add_foreign_key' from schema.rb file
I use SQLite3 and MySQL on the same Rails project but on two different computers. 我在同一Rails项目上但在两台不同的计算机上使用SQLite3和MySQL。 I noticed that the schema.rb
which is generated when I run all migrations looks different for both environments. 我注意到,在我运行所有迁移时生成的schema.rb
在两种环境下看起来都不同。 When I run the migrations in the SQLite3 environment the following statements are removed from the schema.rb
file. 当我在SQLite3环境中运行迁移时,以下语句已从 schema.rb
文件中删除 。
add_index "places", ["user_id"], :name => "places_user_id_fk"
add_foreign_key "places", "users", :name => "places_user_id_fk"
Please note, that I use the foreigner gem which extends migrations with add_foreign_key
and remove_foreign_key
. 请注意,我使用的外国人gem通过add_foreign_key
和remove_foreign_key
扩展了迁移。
Here are the migrations and model relevant to the problem: 以下是与问题相关的迁移和模型:
# 20130123004056_create_places.rb
class CreatePlaces < ActiveRecord::Migration
def change
create_table :places do |t|
t.string :name
t.string :location
t.integer :user_id
t.timestamps
end
end
end
... ...
# 20130123234250_add_foreign_key.rb
class AddForeignKey < ActiveRecord::Migration
def change
add_foreign_key(:places, :users)
end
end
... ...
# user.rb
class User < ActiveRecord::Base
has_many :places
end
... ...
# place.rb
class Place < ActiveRecord::Base
belongs_to :user
end
Question: How can I define the relationship between users
and places
in a way both SQLite3 and MySQL can handle it? 问题:如何以SQLite3和MySQL都可以处理的方式定义users
与places
之间的关系?
The foreigner
README clearly states foreigner
README明确指出
The following adapters are supported: 支持以下适配器:
- sqlite (foreign key methods are a no-op) sqlite (外键方法是禁止操作的)
So your SQLite database does not have foreign key constraints set up because foreigner
doesn't support them . 因此您的SQLite数据库没有设置外键约束, 因为foreigner
不支持它们 。 When db/schema.rb
is generated from the SQLite database, this is why there are no foreign keys specified. 从SQLite数据库生成db/schema.rb
,这就是为什么未指定外键的原因。
The Rails Guide on Migrations mentions foreign keys quite a bit 《 Rails迁移指南》中提到了很多外键
If you need to perform tasks specific to your database (for example create a foreign key constraint) then the
execute
method allows you to execute arbitrary SQL 如果您需要执行特定于数据库的任务(例如,创建外键约束),那么execute
方法允许您执行任意SQL
There is even an example of how to add/remove a foreign key . 甚至还有一个有关如何添加/删除外键的示例。
Having used foreigner
when first starting out with Rails, I suggest you drop it from your Gemfile
and either 刚开始使用Rails时曾使用过foreigner
,建议您将其从Gemfile
,或者
execute
migration method as described in the linked example above (and just make sure all the different RDBMS' support whatever you put into the execute
methods) 使用上面的链接示例中所述的execute
迁移方法(并确保所有不同的RDBMS都支持您在execute
方法中添加的内容) As you pointed out in the comments, SQLite has lacking support for adding foreign keys after the table has been created; 正如您在评论中所指出的那样 ,SQLite在创建表后缺乏对添加外键的支持; they cannot be added through a futre migration in Rails. 无法通过在Rails中进行进一步迁移来添加它们。 I personally suggest you use choice 1 or 3 , as it is going to be more difficult to create a solution through execute
commands in migrations that satisfies the restrictions of SQLite while having the same end result on other RDMS'. 我个人建议您使用选择1或3 ,因为在满足SQLite限制的迁移中通过execute
命令创建解决方案将更加困难,而在其他RDMS上具有相同的最终结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.