错误:必须是plpgsql语言的所有者

24
我正在使用带有Rails(及其依赖项)@v2.3.8的PostgreSQL v9.0.1。由于使用了postgres的全文本能力,我定义了一个表如下:
CREATE TABLE affiliate_products (
    id integer NOT NULL,
    name character varying(255),
    model character varying(255),
    description text,
    price numeric(9,2),
    created_at timestamp without time zone,
    updated_at timestamp without time zone,
    textsearch_vector tsvector,
);
请注意最后一行,这确保active record无法使用标准模式转储器处理它,因此我必须在./config/environment.rb中设置config.active_record.schema_format =:sql; 并且使用rake db:test:clone_structure而不是rake db:test:clone。
这些都不算太出奇,只是不方便 - 然而,rake db:test:clone_structure失败并显示错误:
ERROR: must be owner of language plpgsql
这是由于我在生成的./db/development_schema.sql文件中的第16行所致:
CREATE OR REPLACE PROCEDURAL LANGUAGE plpgsql;
在PostgreSQL v9.0+中,超级用户通过初始模板安装plpsql语言,然后该语言可用于新创建的模式。
如果不解决这个问题,我无法对此项目运行测试,即使手动编辑./db/development_schema.sql也是徒劳无功的,因为每次运行rake db:test:clone_structure时它都会被重新生成(并被rake db:test:clone忽略)。
希望有人能为我解决这个问题?注意: 我同时使用了 pg 0.9.0适配器gem 和 版本为0.7.9.2008.01.28postgres gem - 它们都表现出相同的行为。

我的团队成员运行的是PostgreSQL v8.4,其中语言安装是手动步骤。


1
我考虑过放弃 pl/pgsql 语言,每次手动安装。 - Lee Hambley
5个回答

21

2
这对我有效;但是alter role my_user_name with superuser;实际上是做什么的? - Calvin Cheng
它会将您的 my_user_name 设为 postgres 的超级用户。 - Rahul garg
2
这不是一个合适的解决方案。我不想给这个用户超级用户权限。 - George Daramouskas

21

对于新读者来说,在自己的项目中遇到这个错误后,我阅读了这篇旧文章。我强烈觉得给应用程序的PostgreSQL分配超级用户角色是一个可怕的想法,而更改模板也不理想。由于db:structure:dump添加的参考PSQL命令不需要Rails应用程序的数据库,因此我编写了一个自定义rake任务,在structure.sql文件中注释掉有问题的行。我已经在Github上公开分享了那段代码,作为一个Gist,链接是https://gist.github.com/rietta/7898366


1
你的评论很准确 - 并且在gist中提供的rake文件完美地工作了 - 谢谢! - Ivar
我同意,这确实应该成为这个问题的首选答案。 - tobias.mcnulty
感谢您提供最新的信息,这应该是被接受的答案。 - Alex from Jitbit

8
解决方案如下:
在我的安装中,有标准模板 template0template1。至少在我理解的情况下,当创建一个新数据库时,Postgres 会查找最高编号的 templateN,除非指定了模板。
在这个例子中,由于 template0 包含了 plpgsql,所以 template1 也包含了它... 这样做的想法是你将自定义 template1 来满足站点特定的默认需求,如果你把一切都搞砸了,可以从 template0 恢复 template1
由于我站点特定的要求是在我的 Web 应用程序的自动构建中安装 plpgsql(我们必须遵守8.4的兼容性),所以解决方案很简单:从 template1 中删除 plpgsql,警告/错误就消失了。
如果站点特定的默认值发生变化,我们需要回到默认行为,只需删除 template1 并重新创建它(将使用 template0)。

它不会选择最大编号的模板,除非你指定其他的选择。它会选择template1作为默认选项。 - Peter Eisentraut
谢谢你的澄清,Peter。这是我的错误。如果您删除了“template1”,那么“template0”不就成为默认值了吗?(从而支持了我的假设) - Lee Hambley

2

我在尝试执行RAILS_ENV=development bundle exec rake db:reset时遇到了这个错误。相同的操作(为了我的目的)可以通过执行RAILS_ENV=development bundle exec rake db:drop db:create db:migrate来完成。


0

我只是从structure.sql文件后转储中过滤plpgsql扩展语句:

# lib/tasks/db.rake

namespace :db do
  desc "Fix 'ERROR:  must be owner of extension plpgsql' complaints from Postgresql"
  task :fix_psql_dump do |task|
    filename = ENV['DB_STRUCTURE'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
    sql = File.read(filename)
    sql.sub!(/(CREATE EXTENSION IF NOT EXISTS plpgsql)/, '-- \1')
    sql.sub!(/(COMMENT ON EXTENSION plpgsql)/, '-- \1')
    File.open(filename, 'w') do |f|
      f.write(sql)
    end
    task.reenable
  end
end

Rake::Task["db:structure:dump"].enhance do
  Rake::Task["db:fix_psql_dump"].invoke
end

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