rake db:schema:dump 产生一个空模式

rake db:schema:dump produces an empty schema

我有一个项目目前在 Rails 环境中使用旧版本的 Ruby 并使用 PostgreSQL 数据库。版本是(是的,我知道......别笑,我现在必须支持这个旧版本):

ruby 1.8.7
rails 2.3.11
rake 10.5.0
psql 9.5.7

如果重要的话,这一切都安装在 Ubuntu 16.04 系统上。这一切都在我拥有的旧系统上运行,最终死掉了。所以我在新机器上设置了rvm和这些开发工具版本并复制了数据库。

在新机器上,一切似乎都运行良好除了一些我已经尝试过的 rake 数据库任务。如果我 运行,例如 rake db:schema:dump,我没有错误输出,我得到一个 db/schema.rb 文件,其中包含以下内容:

# This file is auto-generated from the current state of the database. Instead of editing this file,
# please use the migrations feature of Active Record to incrementally modify your database, and
# then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your database schema. If you need
# to create the application database on another system, you should be using db:schema:load, not running
# all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 0) do

end

我尝试了 运行ning rake db:structure:dump 并得到一个错误:

/usr/lib/postgresql/9.5/bin/pg_dump: invalid option -- 'i'
Try "pg_dump --help" for more information.
rake aborted!
Error dumping database
/home/mark/.rvm/gems/ruby-1.8.7-p374@caplus/gems/rails-2.3.11/lib/tasks/databases.rake:287
/home/mark/.rvm/gems/ruby-1.8.7-p374@caplus/bin/ruby_executable_hooks:15
Tasks: TOP => db:structure:dump
(See full trace by running task with --trace)

我主要担心的是无法转储架构。我不明白它如何运行没有错误,但没有生成架构。正如我最初提到的,应用程序 运行 通过 script/server 运行良好。我还从控制台 运行 ActiveRecord::SchemaDumper.dump 得到了完全相同的结果(我猜这是意料之中的,因为这可能是 rake 任务 运行s)。但是从控制台,我可以很好地检查任何模型和数据。都在那里。

关于架构文件为何为空的任何想法?我希望以前有人见过这种现象。我已经做了很多搜索 rake db:schema:dump 的失败模式,但找不到任何地方提到的这种特殊症状。

我做了一些挖掘并确定 PostgresqlAdaptertables 方法返回一个空列表,即使它与数据库有有效连接。适配器源在这里:

gems/activerecord-2.3.11/lib/active_record/connection_adapters/postgresql_adapter.rb

该方法如下所示:

  # Returns the list of all tables in the schema search path or a specified schema.
  def tables(name = nil)
    schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
    query(<<-SQL, name).map { |row| row[0] }
      SELECT tablename
        FROM pg_tables
       WHERE schemaname IN (#{schemas})
    SQL
  end

schema_search_path 返回的字符串类似于 "\"$user\", public"。处理时,前面的空白与 "public" 一起携带,因此查询正在检查架构名称为 "\"$user\""" public" 的架构,因此它与架构不匹配"public".

的名字

我只是像这样破解了代码,现在我的 rake db:schema:dump 工作正常:

    schemas = schema_search_path.split(/,/).map { |p| quote(p.strip) }.join(',')

我怀疑有更好的方法来真正解决问题,但这对我来说很可靠。更何况在这一点上,我使用的版本太旧了,也许没有人在乎。我确实看过 tables 的后期实现,它们有点不同。