Как использовать Flyway в среде MS SQL Server с несколькими схемами?

У нас есть мультитенантное приложение SaaS, использующее стратегию «мультисхемы», то есть у каждого клиента есть выделенная схема в одном экземпляре базы данных. Мы используем MS SQL Server в качестве базы данных, которая переключается между схемами посредством настройки «схемы по умолчанию» для «пользователей» SQL Server. Например, клиенты A, B и C настроены в SQL Server следующим образом:

  • Клиент A: user_A со схемой по умолчанию schema_A
  • Клиент Б: user_B со схемой по умолчанию schema_B
  • Клиент C: user_C со схемой по умолчанию schema_C ... и так далее.

В нашем приложении мы переключаем соединение с источником данных так, чтобы оно указывало на правильную схему для каждого клиента, устанавливая «пользователя» SQL Server в соединении, выполняя следующий SQL перед каждым запросом:

EXECUTE AS USER = 'user_A';

Это создает некоторые проблемы для нас при попытке использовать Flyway для управления состоянием версий схемы - глобальным образом. Поскольку поддержка схемы flyway принимает только список имен схем, это не работает для MS SQL Server. Flyway выполняет миграции по схеме по умолчанию пользователя, предоставленной с конфигурацией DataSource; что в случае с SQL Server «пользователь» должен варьироваться в зависимости от клиента / схемы.

В идеале у нас должен быть обратный вызов типа FlywayCallback.beforeEachSchemaMigrate(Connection), который позволит нам установить желаемый пользовательский контекст для каждой схемы, выполняя оператор «Выполнить как пользователь» перед каждой миграцией для каждой схемы. Не знаете, почему этого крючка нет?

Еще один недостаток пролетного пути - это соглашение об использовании первой схемы в списке схем в качестве той, которая содержит таблицу schema_version. Это нежелательно в многопользовательской среде на базе SQL Server. Поскольку мы не можем предположить, что схема, содержащая schema_version таблицу, также является реальной схемой клиента. Имейте в виду, что в приложении SaaS, таком как наше, схемы для каждого арендатора / клиента создаются / уничтожаются на лету. Когда пользователь регистрируется, часть процесса подготовки создает новую схему на основе некоторых соглашений. Итак, список схем динамичен для нас.

В идеале мы можем указать Flyway использовать данную схему для создания таблицы schema_version, не пытаясь выполнить миграции по этой схеме. Обычно это схема dbo (которая является схемой по умолчанию в SQL Server). Мы используем схему dbo для хранения таблиц, которые являются глобальными по своей природе для всех клиентов, schema_version будет считаться глобальной таблицей.

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

 - dbo.schema_version
 - schema_A.my_tables
 - schema_B.my_tables
 - schema_C.my_tables

Все вышеперечисленные схемы находятся в одном «состоянии», продиктованы и контролируются dbo.schema_version таблицей.

Возможно ли это сейчас?


person Sheraz Khan    schedule 15.07.2014    source источник


Ответы (1)


Вы должны по-другому подойти к проблеме. Вместо одного выполнения Flyway для всех выберите одно для каждой схемы. Вы можете заключить Flyway в цикл и снабдить его правильной конфигурацией для одного арендатора на итерацию. У вас будет одна таблица schema_version для каждого клиента, но все они могут иметь индивидуальные имена и по-прежнему жить в схеме dbo.

person Axel Fontaine    schedule 16.07.2014
comment
Это правда, и у меня уже есть доказательство работоспособности концепции, в которой я перебираю каждую схему и создаю новый экземпляр Flyway для каждой схемы, что хорошо работает (это наш план B). Фактически, в этом случае мы не хотели бы помещать таблицу schema_version в dbo, поскольку она не будет глобальной, они будут находиться в соответствующей схеме. Однако обратная сторона этого заключается в том, что у нас нет гарантии, что все схемы в одной базе данных находятся в одном и том же точном состоянии. Одна схема может иметь версию 2.0.1, а другая - 2.0.2, чего мы пытаемся избежать. Есть ли причина для отсутствия обратного вызова схемы? - person Sheraz Khan; 16.07.2014
comment
На данный момент мы будем использовать отдельный экземпляр Flyway для каждой схемы. Оказывается, это может быть лучший подход по ряду других причин. - person Sheraz Khan; 23.07.2014
comment
Нет, не можешь. Это работает в любой базе данных, кроме сервера sql, о котором идет речь. Если, конечно, я чего-то не упускаю. - person Jasper; 19.07.2018
comment
Мне не хватало: заполнителей. Я думаю, что ответ будет лучше с упоминанием о них (и я действительно не могу изменить свой голос без изменения ответа), но я не совсем знаю, как включить упоминание в этот ответ. - person Jasper; 20.07.2018