ActiveRecord::NoEnvironmentInSchemaError

32

我正在尝试在我的新升级应用程序(Rails 5)上执行与数据库相关的操作,但是我无法在本地执行破坏性数据库命令。
rails db:resetrails db:drop

跟踪结果如下,

rails db:drop --trace
** Invoke db:drop (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Invoke db:check_protected_environments (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config
** Execute db:check_protected_environments

rails aborted!
ActiveRecord::NoEnvironmentInSchemaError: 

Environment data not found in the schema. To resolve this issue, run: 

    bin/rails db:environment:set RAILS_ENV=development

我迄今为止尝试过的方法有:

  1. 设置 bin/rails db:environment:set RAILS_ENV=development,但仍然出现错误。
  2. 手动设置环境变量为development。

这些都没有帮助。我正在寻找解决方法或解决方案。


也许这个链接有用:https://github.com/rails/rails/issues/23279#issuecomment-267087520 - Puhlze
如果这是你的问题,我们在Rails 5.0.x上使用MySQL 8.x时遇到了这个问题。我们不得不升级Rails到2.x才能解决这个问题。 - Joshua Pinter
5个回答

31

修复 ActiveRecord::NoEnvironmentInSchemaError 的两种方法

其他答案已经很好地描述了这个问题,但缺少适当的解决方案。希望本答案能够帮助那些遇到这个问题的人。

为什么会出现这个错误

这个错误消息的出现是由于这个 pull request引起的,该请求旨在防止在生产数据库上执行破坏性操作。正如u/pixelearth正确指出的,Rails 4.2将ar_internal_metadata表中的“key”字段定义为整数,而Rails 5+(包括Rails 6)期望它是一个字符串,并且值为environment。当Rails 5和Rails 6运行这个安全检查时,它们不正确地引发一个ActiveRecord::NoEnvironmentInSchemaError,因为代码与Rails 4模式格式不兼容。

修复方法1:覆盖Rails 5+中的安全检查

**请记住,安全检查是作为许多用户意外删除生产数据库的结果而实施的。正如问题所描述的,这些操作是具有破坏性的。

从终端:

rails db:drop RAILS_ENV=development DISABLE_DATABASE_ENVIRONMENT_CHECK=1
# and/or
rails db:drop RAILS_ENV=test DISABLE_DATABASE_ENVIRONMENT_CHECK=1

正如在这里所提到的,DISABLE_DATABASE_ENVIRONMENT_CHECK=1标志会禁用环境检查。之后,您可以运行rake db:create RAILS_ENV=development(例如)来重新创建具有正确模式的数据库,其中包括ar_internals_metadata表。

修复方法2:回滚至Rails 4,删除数据库,返回Rails 5+并重新创建

从终端开始:

git log
# grab the commit hash from before the upgrade to Rails 5+

git checkout **hash_from_rails_4**
rake db:drop RAILS_ENV=development
rake db:drop RAILS_ENV=test

git checkout master

# now things should work
rails db:migrate

请再次确保在覆盖此功能时不要指向生产数据库。或者,您可以直接修改此表的模式。如果您在生产环境中遇到此错误,则可能需要采取这种方法。


2
对于 Fix #2,您不需要回退到 Rails 4 版本来删除数据库;相反,只需自己删除数据库并重试即可(这对我有效);例如:psql,然后使用 \l 查找我的测试数据库名称,然后使用 drop database my_project_test; 将其删除,然后退出。然后我就可以继续了。感谢您帮助我找到这个解决方案! - skplunkerin

14

出现这个问题的原因是你的 ar_internal_metadata 表被删除或更改了。如果你无法通过命令行删除数据库,你需要通过DBMS或数据库客户端进行操作。然后,只需运行 rails db:create db:migrate 来创建并运行迁移。


5

为了后人,我的问题是这个模式是由一个Rails 4应用程序生成的,使用它的当前应用程序是Rails 5。随着Rails 5,ar_internal_metadata表的结构略有变化。关键字段需要是一个字符串,并包含单词“environment”,而不是整数。只有当这样更改时,此错误才会消失。

在Rails 5中,它应该看起来像这样

enter image description here

请将 ar_internatl_metadata #key 的类型更改为字符串...

我的情况有点不寻常,涉及到一个共享同一数据库的Rails 4应用程序和Rails 5应用程序。当我需要“更新”时,我有一个任务:

  puts "Modifying Rails 4 schema to fit Rails 5 schema"
  file_name = "./db/schema.rb"
  rails_4_ar_internal_metadata = 'create_table "ar_internal_metadata", primary_key: "key", force: :cascade do |t|'
  rails_5_ar_internal_metadata = 'create_table "ar_internal_metadata", primary_key: "key", id: :string, force: :cascade do |t|'
  new_schema = File.read(file_name).gsub(rails_4_ar_internal_metadata, rails_5_ar_internal_metadata)
  File.write(file_name, new_schema)

那么你用来纠正问题的代码步骤是什么? - lacostenycoder
你用GUI修改了这个吗?你知道怎么用纯代码实现吗? - lacostenycoder

2

控制台 Rails

bin/rails db:environment:set RAILS_ENV=development

1

我有

bundle exec rake db:drop
rake aborted!
ActiveRecord::NoEnvironmentInSchemaError: 

Environment data not found in the schema. To resolve this issue, run: 

        rails db:environment:set RAILS_ENV=development

实际上,只需运行rails db:environment:set RAILS_ENV=development就可以解决问题。

为什么会出现这种情况?

这是因为我试图删除数据库并创建/迁移它,但是我在迁移中有一个语法错误(数据类型和列名放错了位置)。检查您的迁移文件是否有任何愚蠢的错误。

具体来说,我有:

t.submitted :boolean, default: false

替代

t.boolean :submitted, default: false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接