我正在尝试为传统的Rails系统提供更多当前标准,但是在测试数据库反映通过迁移进行的schema.rb
加上更改的状态时遇到了问题。
tl; dr 运行rake minitest:all
是否会调用与rake db:schema:load
相同的代码?
该系统最初是由非软件工程师,不了解Rails等人设置的。添加了几种特定于MySQL的类型(例如unsigned int
),这些类型并不是使用Rails& #39;迁移和schema.rb
。因此,系统使用了structure.sql
,并且对于如何更新,检入git等等非常草率。
此外,稍后某人决定替换一些常用的数字,自动递增主键id
字段,其中varchar
包含自生成GUID。字段名称仍为id
,但它是一种新的数据类型。
但是所有数百个测试(他们做了编写了大量测试)都是基于id而不是夹具名称写入参考夹具实例,而且夹具等之间存在依赖关系。与更新测试相比,他们决定坚持使用旧模式(使用数字id
)进行测试,并使用新模式(使用id
中的varchar GUID)进行生产。
OP深呼吸......
各种环境的数据库不同步,有数百次迁移,但由于"开发"数据库被共享了......嗯,你知道,这是一团糟。
我正在尝试修复所有这些,并最终转移到PostgreSQL。
我使用RAILS_ENV=production rake db:structure:dump
从本地生产数据库中转储了架构 - 这产生了一个权威的structure.sql
。我创建了一个新的开发数据库,并使用rake db:structure:load
加载了它的模式 - 我仔细比较了生产和开发模式,它们是相同的,甚至是我上面提到的特定于MySQL的unsigned int。
我想转而使用schema.rb
有两个原因。首先,我想进入一个不依赖于MySQL的系统。其次,当使用structure.sql
时,我们检查一个文件,该文件具有自动增量值,数据库设置和任何机器的其他特征,它们运行最新的db:migrate
。这可能会产生我宁愿避免的问题。
因此,我在本地更改了:sql
的配置设置,以使用:ruby
设置生成schema.rb
。
但是schema.rb
真的不喜欢将id
字段转换为varchar
的想法 - 我确保所有使用此字段的模型都声明{ {1}},然后我创建了一个新的迁移来替换所有旧的迁移,"汇总迁移",其内容主要是新的self.primary_key = :id
,但在几个方面进行了修改。
特别是,schema.rb
字段是GUID id
,我设置了这样的表(从迁移中):
varchar
所以:
class RolledUpStateAsOf20150403 < ActiveRecord::Migration
def up
# ... all other table definitions in the system
create_table "users", :id => false, :force => false do |t|
t.string "id", :limit => 36, :default => "", :null => false
t.string "login"
# and all the other user fields
end
execute("ALTER TABLE users ADD PRIMARY KEY (id);")
#...
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
阻止迁移创建正常ID :id => false
以确保此迁移不会对生产数据库进行核对:force => false
包含大小和其他类似主键的设置t.string "id"
将id声明为主键每次我在将来创建新的迁移时,execute(ALTER TABLE ...)
都会更新 - 它现在不会准确(直到我们以后删除那些古怪的schema.rb
字段) 。迁移将尊重正常的Rails实践。
一旦生产,登台,开发和其他数据库同步,那么一切都很顺利。
除非我们测试。
我正在使用minitest运行测试,如下所示:
id
然后我开始看到错误,错误是由于RAILS_ENV=test rake db:drop
RAILS_ENV=test rake db:create
RAILS_ENV=test rake db:migrate
RAILS_ENV=test rake minitest:all
列被定义为id
而不是int
。
如果我在运行minitest之前检查架构 (在varchar
,drop
之后,以及我的神奇迁移),那么它是正确的:时髦的主键是{{1根据需要。
但是在测试期间的某个地方看起来模式正在变回Rails标准。我可以返回并检查ID列返回到create
的架构。
据推测,架构是从实际的varchar
生成的。
这是正常/预期的行为吗?关于如何实现我的目标的任何建议,简单地说:
int
基于GUID的schema.rb
字段varchar
答案 0 :(得分:2)
好的,所以我相信以下是真的:minitest,或者测试做在db:schema:load
中运行时运行db:structure:load
...或RAILS_ENV=test
- - 通过运行rake test --trace
或rake minitest:all --trace
可以观察到这一点。
所以,因为我schema.rb
无法完全重新创建数据库,因为名为varchar
的字段奇怪地使用了int
而不是id
...我有恢复使用structure.sql
代替。
解决方案的其余部分,包括添加手动修改版本的schema.rb
作为第一个&#34;汇总&#34;迁移工作得很好,随后的迁移也很好。将来的某个时候,我会将ids变回自然形态;就目前而言,如果不是优雅的话,这是一个合适的解决方案。