我试图将遗留的Rails系统提升到当前的标准,但在获取测试数据库以反映schema.rb的状态以及通过迁移进行的更改时遇到了问题。
tl;博士确实运行rake minitest:all调用与rake db:schema:load相同的代码
环境
原制度状态
该系统最初是由非软件工程师、不了解Rails等人建立的。添加了几种特定于MySQL的类型(例如,unsigned int),这些类型不支持使用Rails的迁移和schema.rb。因此,系统使用了structure.sql,对于如何保持更新、登录到git等等,非常草率。
此外,在以后的某个时候,有人决定用包含自生成GUID的varchar替换一些通常的数字自动递增的主键varchar字段。字段名仍然是id,但它是一个新的数据类型。
但是,所有的数百个测试(他们确实编写了很多测试)都是基于in而不是基于夹具名称来引用夹具实例的,并且在夹具之间存在依赖关系等等。与其更新测试,他们决定坚持旧模式(使用数字id)进行测试,并使用新的模式(在id中使用varchar )进行生产。
OP深吸一口气..。
不同环境的数据库不同步,有数百个迁移,但是它们停止工作,因为“开发”数据库是共享的,而且.嗯,你知道,那是个烂摊子。
我正试图修复所有这些问题,并最终迁移到PostgreSQL。
我所做的
我在本地使用RAILS_ENV=production rake db:structure:dump从生产数据库中转储模式--这产生了一个权威的structure.sql。我创建了一个新的开发数据库,并使用rake db:structure:load加载了它的模式--我仔细地比较了生产模式和开发模式,它们是相同的,甚至上面提到的MySQL特定的无符号int。
我想使用schema.rb有两个原因。首先,我想介绍一个不依赖MySQL的系统。其次,在使用structure.sql时,我们签入的文件具有自动增量值、DB设置和运行最新db:migrate的机器的其他特性。这可能会产生一些我希望避免的问题。
因此,我在本地将配置设置从:sql更改为使用:ruby设置来生成schema.rb。
但是schema.rb真的不喜欢把id字段转换成varchar的想法--我已经确定了所有使用这个声明self.primary_key = :id的模型,然后我创建了一个新的迁移来取代所有旧的迁移,一个“汇总迁移”,它的内容主要是新的schema.rb,但是通过几种方式进行了修改。
特别是,在id字段是GUID 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 => false以防止迁移创建正常id。:force => false,以确保这种迁移不会影响生产DBt.string "id"execute(ALTER TABLE ...)将来每次我创建一个新的迁移时,schema.rb都会被更新--目前它是不准确的(直到我们稍后处理掉那些古怪的id字段)。迁移将遵循向前推进的常规Rails实践。
一旦生产、分期、开发和其他数据库同步,一切就都好了。
除了我们测试的时候。
为什么当我运行Minitest的时候,这个就不能工作了?
我正在进行以下最小的测试:
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而不是varchar。
如果我在运行最小模式(在drop、create和神奇迁移之后)之前检查模式,那么它是正确的:时髦的主键是varchar。
但是,在测试过程中的某个地方,模式似乎正在被更改回Rails标准。我可以返回并检查ID列返回到int的模式。
据推测,模式是从实际的schema.rb生成的。
这是正常/预期的行为吗?任何关于如何实现我的目标的建议,都是简单的:
varchar GUID的id字段。structure.sql发布于 2015-04-14 19:11:30
好的,所以我相信以下是正确的:最小的,或测试运行db:schema:load .或者db:structure:load在RAILS_ENV=test中运行时--这可以通过运行rake test --trace或rake minitest:all --trace来观察。
因此,因为我的schema.rb无法完全重新创建数据库,这是因为在名为id的字段中使用了varchar而不是int .我不得不转而使用structure.sql。
解决方案的其余部分,包括在第一次“汇总”迁移时添加一个手工修改的schema.rb版本,运行良好,随后的迁移也很好。将来的某个时候,我将把ids转换成它们的自然形式;就目前而言,这是一个合适的解决方案,如果不是优雅的话。
https://stackoverflow.com/questions/29547518
复制相似问题