переопределить свойства локальной ликвидазы, которые все еще видны во включенных файлах - PullRequest
0 голосов
/ 17 октября 2019

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

Основываясь на различных идеях, которые я нашел в сети, я попробовал это:

db / templates / 0004-create-validity-period-data-template.xml

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
                            http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">

    <include file="../templates/0002-create-versioned-data-template.xml" relativeToChangelogFile="true" />

    <changeSet author="${table.author}" id="Create ValidityPeriodData for ${table.name}" >
        <comment>Create columns of super class ValidityPeriodData for table ${table.name}</comment>
        <addColumn tableName="${table.name}" >
            <column name="valid_from" type="date" remarks="the earliest point in time when this entry is valid" />
            <column name="valid_until" type="date" remarks="the last point in time when this entry is valid" />
        </addColumn>
    </changeSet>

</databaseChangeLog>

db / changelog / 0017-create-credential-table.xml

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
                            http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">

    <property name="table.name" value="login" />
    <property name="table.author" value="guess ;-)" />

    <include file="../templates/0004-create-validity-period-data-template.xml" relativeToChangelogFile="true" />

    <changeSet author="${table.author}" id="Create Credential table">
        <addColumn tableName="${table.name}">
            <column name="login_id" type="${uuid_type}"/>
            <column name="password" type="VARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="salt" type="VARCHAR(128)"/>
        </addColumn>
        <addForeignKeyConstraint baseColumnNames="login_id"
                                 baseTableName="${table.name}"
                                 constraintName="fk_credential_of_login"
                                 onDelete="RESTRICT"
                                 onUpdate="RESTRICT"
                                 referencedColumnNames="id"
                                 referencedTableName="login"/>
    </changeSet>

</databaseChangeLog>

Проблема

Свойства (table.name, table.author) по умолчанию global="true", что означает, что онивиден во всех файлах наборов изменений, но их нельзя перезаписать / переопределить. Так что это работает только для одной таблицы, которая побеждает цель. Если я объявлю их как global="false", я могу переопределить их для каждой таблицы, для которой нужны эти столбцы, однако теперь включенные файлы не видят эти свойства.

Вопрос

Есть ли способ переопределить или перезаписать свойства для различных файлов наборов изменений (например, что делает global="false"), но при этом они ведут себя как global="true" во включаемых файлах даже рекурсивно.

Ответы [ 2 ]

0 голосов
/ 25 октября 2019

Фон

Я взглянул на исходный код ликвибазы. Оказывается, текущая реализация (в версиях 3.6.2, 3.6.3, 3.8.0) работает немного странно.

private ChangeLogParameter findParameter(String key, DatabaseChangeLog changeLog) {
    ChangeLogParameter result = null;

    List<ChangeLogParameter> found = new ArrayList<>();
    for (ChangeLogParameter param : changeLogParameters) {
        if (param.getKey().equalsIgnoreCase(key) && param.isValid()) {
            found.add(param);
        }
    }

    if (found.size() == 1) {
        // this case is typically a global param, but could also be a unique non-global param in one specific
        // changelog
        result = found.get(0);
    } else if (found.size() > 1) {
        for (ChangeLogParameter changeLogParameter : found) {
            if (changeLogParameter.getChangeLog().equals(changeLog)) {
                result = changeLogParameter;
            }
        }
    }

    return result;
}

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

Таким образом, при первом обнаружении параметра он фактически обрабатывается, как если бы он был global=true независимо от того, имеет ли это местоили нет.

Второй глобальный параметр с таким же именем не будет записан. Однако будет записан второй локальный параметр.

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


Ответ

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


Решение?

Я отправил отчет об ошибке с liquibase CORE-3493 и предоставил возможное решение на GitHub. Мы должны выяснить, когда и когда это будет включено.

Я сейчас использую свою собственную разветвленную версию, которая может обработать сценарий использования, описанный в моем вопросе.

0 голосов
/ 17 октября 2019

Я думаю, у вас неправильное представление об использовании наборов изменений в жидкой базе.

Набор изменений должен быть атомарным и следовать концепции «одно действие - один набор изменений». Это не должна быть какая-то «функция многократного использования». Такой подход может повредить схему вашей базы данных. По этой причине вы не удаляете старые наборы изменений

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

Также ознакомьтесь с этой статьей: Обрезка файлов изменений ChangeLog

...