Rails и схемы Postgres

Вводная

С недавних пор начал в качестве СУБД использовать Postgres. Меня очень сильно привлекают в нем схемы, или как их часто называют — пространство имен(namespace), это конечно не единственное достоинство и даже не главное, а лишь приятная мелочь. Поэтому когда мы с другом начали думать о своем пилотном проекте естественно я в качесстве СУБД выбрал именно Postgres. Но вот поставить его на рельсы так, как хочется, оказалось не так просто…

Первое что я сделал это создал проект на рельсах:

rails <project name> -d postgresql 

Тут все просто, создается базовая струкрура проекта и в database.yml создается уже конфигурация с подключением к postgres:

development:   adapter: postgresql   encoding: unicode   database: app_development   pool: 5   username: www   password: 123   host: localhost   port: 5432 

Да, чтобы все работало нужно не забыть подключить gem — pg 🙂

Проблема

Я столкнулся с тем, что я не могу создать миграцию на создание схемы, точнее я могу ссоздать, но если после этой миграции есть еще одна, которая хочет создать таблицу в этой схеме, то тут начинаются проблемы… Как я понял все миграции запускаются в одной транзакции и поэтому не получается оздать схему и сразу создать в ней таблицу.

В ручную я принципиально не хотел создавать схемы, было желание автоматизировать процесс:

rake db:migrate 

Что я пытался сделать

Добавил в database.yml search_path: «app, public» — не помогло, т.к. на момент запуска мигрейшена, создающего схему app, ее еще нет и поэтому приложение не может подключиться к базе. Как только не подходил к search_path, но у меня так и не получилось.

Далее пришло в голову мысль кастомизировать rake-task db:migrate. Крутил ввеертел, не вышло, что-то да шло не так как хочется.

Вариант который меня устроил

Я решил зазложить все миграции по директориям, одну директорию я назвал app — туда я складываю миграции для таблиц, которые принадлежат схеме app, далее создал директорию schema — в ней расположены все миграции, создающие схемы для БД.
Дальше я начал думать, а как же мне запустить лишь те миграции которые лежат в папке schema, а потом лишь все остальные. Я начал посматривать в сторону создания своего rake-task, который выглядит следующим образом:

# ------------------------------------------------------------- # =Description: # Rake task for creating postgres schemas # ------------------------------------------------------------- namespace :db do   desc "Run migration for creating schemas"   task :create_schemas => :environment do     ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true     ActiveRecord::Migrator.migrate("db/migrate/schema", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)   end end 

Довольно простой таск, на что тут стоит обратить внимание:

  • Таск создается в неймспейсе db
    namespace :db 
  • Запускаются только миграции из определенной директории
    ActiveRecord::Migrator.migrate("db/migrate/schema", ENV["VERSION"] ? ENV["VERSION"].to_i : nil) 

Как это все работает

Теперь для накатывания миграций я делаю следующее:

rake db:create_schemas rake db:migrate 

Заключение

Мучить Ruby и RoR я начал совсем недавно, возможно найдется более идеальное решение данной проблемы со схемами в RoR, но текущий вариант меня пока устраивает, может кто-то знает другой, более простой и элегантный способ?

ссылка на оригинал статьи http://habrahabr.ru/post/161693/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *