Как управлять миграцией, когда несколько приложений используют одну и ту же базу данных в Ruby?

У меня есть приложение Rails и приложение Sinatra, использующие одну и ту же базу данных. Приложение Sinatra использует ActiveRecord.

Могу ли я запускать миграции из каждого приложения, как если бы они были в одном приложении? Это вызовет какие-то проблемы?

Файл schema.rb в приложении Rails отслеживает текущую миграцию через

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

но как приложение Sinatra узнает текущую версию базы данных?

Рельсы 3.2.2, Руби 1.9.3.


person B Seven    schedule 27.11.2012    source источник


Ответы (5)


Столбец версии в таблице schema_migrations соответствует отметке времени в начале примера файла миграции ruby: 20130322151805_create_customers.rb Таким образом, если два или более приложений вносят вклад в таблицу schema_migrations, откат будет невозможен, если рельсы не смогут найти метод down() (поскольку он не найдет файл миграции, содержащийся в другом приложении, например db/migrate/...)

У меня сейчас именно такая ситуация, и я решил использовать главное приложение ActiveRecord, которое управляет миграцией и преобразованием данных по мере развития нашей базы данных. Имейте в виду, что часть сделки также заключается в обновлении моделей. На это ушло много времени, поэтому мы рассматриваем возможность разделения БД на бизнес-домены и предоставления API (JSON) для запроса данных поддержки для другого приложения. Таким образом, каждое приложение управляет своим доменом и отвечает за предоставление данных через API.

С уважением.

person Dale    schedule 22.03.2013

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

  • разделить базу данных на две части, если это возможно, чтобы каждое приложение отвечало за свою собственную базу данных/миграции.

  • одно приложение считается «главной» базой данных и использует другую базу данных для данных, специфичных для второго приложения, но делает так, чтобы оно подключалось к обеим базам данных (каждое приложение по-прежнему применяет миграции только к одной базе данных)

Если вам нужно обмениваться данными между несколькими приложениями, другим вариантом является реализация службы REST в одном и использование ее в другом, вы можете взглянуть на драгоценный камень винограда для простого способа сделать это.

Редактировать: я понимаю, что забыл сказать о переносе активной записи, больше нет никакой «версии» схемы, что делает активная запись, так это то, что она читает все ваше имя файла миграции, извлекает их идентификатор (начальную часть) и проверяет, есть ли у них уже применялись, поэтому теоретически вы можете запускать миграции из двух приложений в одной и той же базе данных, если они не мешают. Но если обе миграции действуют на одни и те же таблицы, вы почти наверняка столкнетесь с большими проблемами в какой-то момент.

person Schmurfy    schedule 27.11.2012
comment
Я не думаю, что какое-либо из этих решений будет работать, потому что им обоим нужно использовать одни и те же данные, и я думаю, что проще запускать одну базу данных... Но, может быть, я смогу поместить все миграции в приложение Rails... - person B Seven; 27.11.2012
comment
Я добавил объяснение о том, как работает миграция ActiveRecord, насколько независимы оба приложения? Если вы можете распространять/устанавливать/развертывать их оба одновременно, вы можете решить, что один из них отвечает за миграцию и, возможно, даже иметь их обоих в одном и том же git/svn/.... - person Schmurfy; 28.11.2012

Я не согласен со Шмурфи, даже если представленные им варианты действительны, обмен данными через REST немного излишен (конечно, его довольно легко реализовать с помощью ruby/rails).

Если ваш случай прост, вы можете просто использовать одну базу данных из обоих приложений, и, поскольку вы используете AR в них обоих, у вас нет проблем с управлением версиями, AR позаботится об этом.

Также я не знаю, что произойдет, если вы запустите db: migrate из обоих приложений одновременно, если вы используете более низкую СУБД, такую ​​как mysql, которая не разрешает DDL в транзакции, конечно, ничего хорошего.

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

person Andreas    schedule 27.11.2012
comment
Я просто хотел указать на не обязательно очевидную ловушку. - person Andreas; 27.11.2012

Миграции Rails сохраняют текущую версию базы данных в таблице schema_migrations в базе данных. Таким образом, оба ваших приложения смогут проверить текущую версию.

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

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

person Matt    schedule 28.11.2012

Я решил поместить все миграции в приложение Rails, потому что:

  1. Так как есть только одна база данных
  2. Rails управляет миграциями

Это сработало хорошо.

Это упрощает систему, поскольку все миграции хранятся в одном месте. И приложению Sinatra в любом случае не нужно знать о них.

person B Seven    schedule 09.12.2012
comment
что не так с моим ответом? Вы выбрали один из вариантов второго варианта, который я упомянул... - person Schmurfy; 10.12.2012
comment
Есть только одна база данных. - person B Seven; 10.12.2012