Включение hstore при развертывании с помощью Rubber

Я развертываю приложение Rails, использующее PostgreSQL и HSTORE.

Для его развертывания я использую резину.

Все работает, за исключением того, что HSTORE не включен должным образом. Когда выполняется миграция, содержащая execute("CREATE EXTENSION hstore"), я получаю следующие ошибки:

** [out :: production.---] 
** [out :: production.---] -- execute("CREATE EXTENSION hstore")
** [out :: production.---] 
** [out :: production.---] rake aborted!
** [out :: production.---] An error has occurred, this and all later migrations canceled:
** [out :: production.---] 
** [out :: production.---] PG::Error: ERROR:  permission denied to create extension "hstore"
** [out :: production.---] HINT:  Must be superuser to create this extension.

Сценарий, создающий экземпляр postgres, имеет следующий код:

create_user_cmd = "CREATE USER #{env.db_user} WITH NOSUPERUSER CREATEDB NOCREATEROLE"

поэтому я думаю, что проблема может быть связана с установленным здесь атрибутом NOSUPERUSER.

Есть ли способ включить hstore с использованием резины, сохранив при этом большинство сгенерированных файлов без изменений?


person pgb    schedule 01.03.2013    source источник
comment
Вы пробовали драгоценный камень activerecord-postgres-hstore? Он устанавливает функциональность hstore путем миграции.   -  person R Milushev    schedule 01.03.2013
comment
Проблема заключается в разрешениях при выполнении миграции. У меня установлен драгоценный камень.   -  person pgb    schedule 01.03.2013


Ответы (2)


Проблема в том, что Rubber создает пользователя БД как NOSUPERUSER. Мой обходной путь заключается в создании задач, которые выполняются до и после deploy:migrate capistrano, которые изменят пользователя на SUPERUSER и обратно.

Вот код:

namespace :rubber do

  namespace :project do

    before "deploy:migrate", "rubber:project:add_pg_superuser_and_enable_hstore"
    after "deploy:migrate", "rubber:project:remove_pg_superuser"

    task :add_pg_superuser_and_enable_hstore,
         :roles => [:postgresql_master, :postgresql_slave] do
      alter_user_cmd = "ALTER USER #{rubber_env.db_user} SUPERUSER"
      create_hstore_cmd = "CREATE EXTENSION IF NOT EXISTS hstore;"
      rubber.sudo_script "add_superuser_create_hstore", <<-ENDSCRIPT
        sudo -i -u postgres psql -c "#{alter_user_cmd}"
        sudo -i -u postgres psql -c "#{create_hstore_cmd}"
      ENDSCRIPT
    end

    task :remove_pg_superuser, :roles => [:postgresql_master,
                                          :postgresql_slave] do
      alter_user_cmd = "ALTER USER #{rubber_env.db_user} NOSUPERUSER"
      rubber.sudo_script "add_superuser_create_hstore", <<-ENDSCRIPT
        sudo -i -u postgres psql -c "#{alter_user_cmd}"
      ENDSCRIPT
    end

  end

end
person pgb    schedule 01.03.2013
comment
Это должен быть принятый ответ. Я добавил его в конец моего config/deploy.rb, и все снова заработало. Спасибо! - person eddieroger; 10.07.2014
comment
Я не думаю, что мы должны рекомендовать людям включать суперпользователя в качестве универсального ответа. Rubber создает файлы, которые вы можете изменять. Вам нужно просто изменить сгенерированный файл deploy-postgresql.rb, чтобы создать расширение вместе с другим выполняемым привилегированным SQL. - person nirvdrum; 21.01.2016

Другой вариант — не привлекать суперпользователя postgres при развертывании, а создать шаблон (или использовать шаблон по умолчанию) и установить расширение в шаблоне. Затем, когда вы создаете базу данных, в ней будет установлено расширение.

Хорошие ответы здесь и здесь.

person Kristiina    schedule 31.12.2013