首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails:最小限度是否使用schema.rb重新创建测试模式?

Rails:最小限度是否使用schema.rb重新创建测试模式?
EN

Stack Overflow用户
提问于 2015-04-09 19:42:32
回答 1查看 939关注 0票数 4

我试图将遗留的Rails系统提升到当前的标准,但在获取测试数据库以反映schema.rb的状态以及通过迁移进行的更改时遇到了问题。

tl;博士确实运行rake minitest:all调用与rake db:schema:load相同的代码

环境

  • Rails 3.2.20
  • Ruby 1.9.3
  • 最低值宝石4.6.2
  • 最小-rails 0.5.2
  • MySQL 5.1
  • 本地OS X,测试和生产Linux

原制度状态

该系统最初是由非软件工程师、不了解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的情况下,我像这样设置了表(在迁移中):

代码语言:javascript
复制
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,以确保这种迁移不会影响生产DB
  • 具有大小和其他类似主键设置的t.string "id"
  • 将id声明为主键的末尾的execute(ALTER TABLE ...)

将来每次我创建一个新的迁移时,schema.rb都会被更新--目前它是不准确的(直到我们稍后处理掉那些古怪的id字段)。迁移将遵循向前推进的常规Rails实践。

一旦生产、分期、开发和其他数据库同步,一切就都好了。

除了我们测试的时候。

为什么当我运行Minitest的时候,这个就不能工作了?

我正在进行以下最小的测试:

代码语言:javascript
复制
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

如果我在运行最小模式(在dropcreate和神奇迁移之后)之前检查模式,那么它是正确的:时髦的主键是varchar

但是,在测试过程中的某个地方,模式似乎正在被更改回Rails标准。我可以返回并检查ID列返回到int的模式。

据推测,模式是从实际的schema.rb生成的。

这是正常/预期的行为吗?任何关于如何实现我的目标的建议,都是简单的:

  • 迁移又起作用了
  • 开发、测试、分期、生产数据库在结构上是相同的。
  • 我现在需要使用疯狂的基于varchar GUID的id字段。
  • 如果可能的话,我宁愿不使用structure.sql
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-14 19:11:30

好的,所以我相信以下是正确的:最小的,或测试运行db:schema:load .或者db:structure:loadRAILS_ENV=test中运行时--这可以通过运行rake test --tracerake minitest:all --trace来观察。

因此,因为我的schema.rb无法完全重新创建数据库,这是因为在名为id的字段中使用了varchar而不是int .我不得不转而使用structure.sql

解决方案的其余部分,包括在第一次“汇总”迁移时添加一个手工修改的schema.rb版本,运行良好,随后的迁移也很好。将来的某个时候,我将把ids转换成它们的自然形式;就目前而言,这是一个合适的解决方案,如果不是优雅的话。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29547518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档