Как обрабатывать синонимы Oracle с Flyway 2.0.1?

Пользуюсь flyway уже давно. Очень хороший / полный инструмент!

На самом деле я столкнулся с неожиданной ситуацией... У меня есть две схемы:

  • Владелец, обрабатывающий таблицы и последовательности
  • Пользователь, использующий синонимы для доступа к объектам владельца

Обычай не хочет, чтобы я давал права «предоставить любой синоним / удалить любой синоним» Владельцу. Но я могу предоставить пользователю «предоставить синоним создания».

Так что мне нужно

  1. Создайте таблицы/последовательности (связанные с владельцем)
  2. Предоставить выбор, удаление... моей пользовательской схеме (связанной с владельцем)
  3. Создайте синоним для пользователя для доступа к объектам владельца (связанным с пользователем)

Пункт 3 моя проблема.

Если я дам владельцу «предоставить любой синоним» и использую заполнители пролетного пути, я могу сделать что-то вроде этого:

CREATE OR REPLACE SYNONYM ${user}.WORKITEMINFO FOR WORKITEMINFO;

Но я не могу ;)

Поэтому решение, которое я реализовал, заключается в использовании миграции Java с использованием другого источника данных, подключенного к схеме пользователя. (Мой MigrationUtils.replacePlaceholders позволяет мне получить доступ к любому из свойств flyway.properties в качестве заполнителя)

private final static String[] queries =
        {"CREATE OR REPLACE SYNONYM TASK_COMMENT FOR ${flyway.user}.TASK_COMMENT"}

@Override
public void migrate(final Connection connection) throws Exception {

    final DataSource dataSource = MigrationUtils.getUserDataSource();

    final Connection connectionForMigrations = dataSource.getConnection();

    final JdbcTemplate jdbcTemplate = new JdbcTemplate(connectionForMigrations);
    new TransactionTemplate(connectionForMigrations).execute(new TransactionCallback<Void>() {

        @Override
        public Void doInTransaction() {

            try {
                for (final String query : queries) {
                    final String replacedQuery = MigrationUtils.replacePlaceholders(query);
                    LOG.debug("Executing SQL: " + replacedQuery);
                    jdbcTemplate.executeStatement(replacedQuery);
                }
            } catch (final SQLException exc) {
                throw new FlywayException("Could not drop synonym", exc);
            }
            return null;
        }
    });

}

Есть ли другой способ разрешить эту ситуацию?

Спасибо!


person Jean-François Houzard    schedule 10.05.2013    source источник
comment
И почему именно оператор создания синонима не работает?   -  person Axel Fontaine    schedule 12.05.2013
comment
Создание синонимов работает, но мне также нужно удалить синонимы. Настоящая проблема заключается в том, что мой клиент не хочет, чтобы я предоставлял владельцу «предоставить любой синоним».   -  person Jean-François Houzard    schedule 13.05.2013


Ответы (2)


Лучшим способом было бы уточнить имя схемы в приложении.

Если это невозможно и приложение использует только SQL (не PL/SQL) для доступа к объектам «Владелец», вы можете вообще избежать синонимов, изменив схему по умолчанию в триггере после входа в систему:

create or replace trigger USERX.a_logon_USERX
after logon on USERX
BEGIN
  EXECUTE IMMEDIATE ('ALTER SESSION SET current_schema=standard');
END;

Однако довольно трудно понять, что этот метод не работает, когда приложение отправляет блоки PL/SQL ("begin ... end;") в базу данных. PL/SQL скомпилирован и поэтому не может учитывать текущую схему.

person HAL 9000    schedule 12.05.2013

Используйте -Dflyway.schemas=OWNER_NAME, пока бежите по пролету.

person Monzurul Haque Shimul    schedule 07.11.2016