Перенос данных из одной базы в любую другую

    В нашем Ruby On Rails 3 приложении возникла необходимость перейти с Sqlite на MySQL. Нужен было простой и действенный способ, без громоздких Perl скриптов и платных утилит, которыми пестрит интернет и в частности StackOverflow.

    Описание


    Лучшим вариантом оказался gem yaml_db, возникший в недрах команды разработчиков Heroku.

    Суть работы гема заключается в том, что он сохраняет дамп данных одной базы в YAML-файл на диск, а затем загружает его в другую базу (технически, конечно, такой подход можно использовать и для бэкапов).

    Преимущество данного подхода в том, что совершенно неважно, с какой базой вы работаете. Теоретически поддерживаются все базы данных, для которых существует ActiveRecord adapter.

    Простейший сценарий использования


    Добавляем yaml_db в Gemfile:
    gem 'yaml_db', :git => 'git://github.com/ludicast/yaml_db.git'

    Запускаем Bundler:
    bundle install

    Начальная конфигурация базы данных:
    config/database.yml
    production:
      adapter: sqlite3
      database: db/production.sqlite3
      pool: 5
      timeout: 5000

    Делаем, собственно, сам дамп:
    export RAILS_ENV=production
    rake db:data:dump


    После этого в db/data.yml должны быть данные вашей базы.

    Если все хорошо, то меняем конфигурацию базы данных на нужную:
    config/database.yml
    production:
      adapter: mysql2
      database: app_production
      username: root
      password: root
      host: localhost
      pool: 5
      timeout: 5000

    Не забудьте добавить необходимый гем в Gemfile.

    Создаем базу и запускаем миграции:
    rake db:create
    rake db:migrate


    Ну и, наконец, загружаем дамп в новую базу:
    rake db:data:load

    Теперь можно запустить сервер и проверить, что все работает.

    Замечания


    Если вы используете ветку Ruby 1.9, то Bundler версии 1.0.10 загружает Psych как YAML engine по умолчанию, который не самым корректным образом работает с некоторыми версиями Rails, поэтому если у вас возникли какие-то проблемы при вставке дампа, то одним из вариантов решения может быть замена Psych на Syck:
    в config/application.rb после строки
    Bundler.require(:default, Rails.env) if defined?(Bundler)
    вставить
    YAML::ENGINE.yamler = 'syck'

    yaml_db может делать не только дамп данных, но еще и структуры базы:
    rake db:dump
    rake db:load

    Первый таск делает дамп данных и структуры, второй создает таблицы и загружает данные.

    Ссылки


    Статья о yaml_db на блоге Heroku
    Ветка yaml_db для Rails 2.x
    Share post

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 16

      0
      Psych ведь только для 1.9 ветки доступен?
        0
        Да, он идет вместе с Ruby 1.9.х
          +1
          я к тому что в статье неплохо было бы указать
            +1
            добавил, спасибо
        0
        мы используем gem install taps
        работает также db:push db:pull
          0
          тоже использую тапс. Отлично гоняет sqlite3 mysql, mysql postgres, sqlite3 postgres.
          Остальные варианты не проверял
          –1
          Прикольно. Я примерно то же самое в свом время руками написал на коленке минут за 10, когда надо было базу менять.
            0
            Хз, а я регексом подправил… Но там было наоборот с MySQL нужно было к SQLite адаптировать.

            Вот только мне интересно что ж это за проект такой где по умолчанию юзался sqlite…
              +3
              Скажу так, что до определенного момента его было более чем достаточно.
              0
              Проблема легко решается использованием всегда mysql или postgres. Неважно какого размера проект.
              А из mysql в postgres можно перегнать используя стандартные средства postgres.

              Поделитесь за какое время вы переконвертировали базу используя yaml файлы?
              Как я понимаю когда приходится переходить уже есть нагрузка и даунтайм приложения критичен даже в ночьное время
                0
                100 мегабайтную базу перенесли за 10 минут, но тут многое зависит от железа, конечно.
                  0
                  100 мб это не серьезно.
                  Можно было обойтись и ActiveRecord::Base.connection.execute(«select * from table»).to_a.to_json
                    0
                    Ну а дальше?..

                    Нужен был простой и надежный способ, без плясок с бубном.
                –1
                Насчет «в любую другую» я бы поспорил. При переносе из sqlite в pg с год назад пришлось писать патч для того чтобы нормально переслись блобы. Постарался конечно сделать универсально, чтобы и в других базах работало, но не проверял.

                С разными типами тоже будут проблемы, например если в одной базе будут boolean тип а в другой такого типа не будет.
                  0
                  С разными типами у yaml_db проблем нет.
                    0
                    Почитайте внимательнее что я написал. Ваша фраза «с разными типами проблем нет» совсем не описывает то что я имел ввиду.

                Only users with full accounts can post comments. Log in, please.