гранулярность изменения первичного ключа - PullRequest
1 голос
/ 10 июня 2019

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

Интересно, как разделить проблемы и правильно выполнить откат.

  1. изменения addColumn и PK в одном наборе изменений
<changeSet author="rahul" id="change_pk">
        <addColumn tableName="posts">
            <column name="aux_id" type="INT" defaultValue="0"/>
        </addColumn>
        <dropPrimaryKey tableName="posts"/>
        <addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
        <rollback>
          <dropPrimaryKey tableName="posts"/>
          <addPrimaryKey tableName="posts" columnNames="id"/>
        </rollback>
    </changeSet>

Что касается меня в этом подходе, так это то, что если я не могу создать столбец, я отброшу PK и создаю его заново, что может повлиять на время отклика БД, если предположить, что таблица довольно большая. Однако это делает все эти изменения атомарными.

  1. Переместить изменения PK в другой набор изменений
<changeSet author="rahul" id="add_col">
        <addColumn tableName="posts">
            <column name="aux_id" type="INT" defaultValue="0"/>
        </addColumn>
</changeSet>
<changeSet author="rahul" id="change_pk">
        <dropPrimaryKey tableName="posts"/>
        <addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
        <rollback>
          <dropPrimaryKey tableName="posts"/>
          <addPrimaryKey tableName="posts" columnNames="id"/>
        </rollback>
</changeSet>

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

1 Ответ

0 голосов
/ 10 июня 2019

Вы можете сделать следующее, используя атрибут runAlways . Кроме того, проверьте различные варианты onFail

<changeSet author="rahul" id="add_col" runAlways="true">
    <preConditions (perhaps, some non-default onFail option) >
        <not>
            <columnExists tableName="posts" columnName="aux_id"/>
        </not>
    </preConditions>
    <addColumn tableName="posts">
        <column name="aux_id" type="INT" defaultValue="0"/>
    </addColumn>
</changeSet>

<changeSet author="rahul" id="change_pk">
    <preConditions>
        <and>
            <columnExists tableName="posts" columnName="aux_id"/>
            <!-- perhaps some other precondition --> 
            <sqlCheck expectedResult="id">
                SELECT key_column_usage.column_name
                FROM   information_schema.key_column_usage
                WHERE  table_schema = SCHEMA()     
                AND    constraint_name = 'PRIMARY' 
                AND    table_name = 'posts' 
            </sqlCheck>
        </and>
    </preConditions>
    <dropPrimaryKey tableName="posts"/>
    <addPrimaryKey tableName="posts" columnNames="id,aux_id"/>
    <rollback>
        <dropPrimaryKey tableName="posts"/>
        <addPrimaryKey tableName="posts" columnNames="id"/>
        <dropColumn tableName="posts" columnName="aux_id">
    </rollback>
</changeSet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...