Проблема модификации столбца временной метки Liquibase & MySQL 5.7 - PullRequest
1 голос
/ 08 ноября 2019

У меня есть столбец с именем updated_time, ему назначен тип данных timestamp:

`updated_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 

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

Итак, я подготовил следующий набор изменений Liquibase:

{
  "databaseChangeLog": [
    {
      "changeSet": {
        "id": "1",
        "changes": [
          {
            "modifyDataType": {
              "columnName": "updated_time",
              "newDataType": "timestamp(3)",
              "tableName": "mytable"
            },
            "addDefaultValue": {
              "columnDataType": "timestamp(3)",
              "columnName": "updated_time",
              "defaultValueComputed": "current_timestamp(3)",
              "tableName": "mytable"
            },
            "addNotNullConstraint": {
              "columnDataType": "timestamp(3)",
              "columnName": "updated_time",
              "tableName": "mytable"
            }
          }
        ]
      }
    }
  ]
}

К сожалению, этот набор изменений всегда дает сбой.

Вот причина:

2019-11-08 00:57:28.624  WARN [] 99326 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.MigrationFailedException: Migration failed for change set ...
     Reason: liquibase.exception.DatabaseException: Invalid default value for 'updated_time' [Failed SQL: (1067) ALTER TABLE maas.mytable MODIFY updated_time timestamp(3)]

Я видел несколько сообщений о том, что в версии 5.7 произошли некоторые изменения в типе данных timestamp. То, что по умолчанию я не могу присвоить ненулевое (нулевое) значение столбцу timestamp. И для того, чтобы это исправить, мне нужно было внести некоторые изменения в саму конфигурацию сервера. Давайте представим, что у меня ограниченный доступ к серверу, и я не могу просто пойти и изменить конфигурацию, есть ли элегантный способ обойти эту проблему в Liquibase?

1 Ответ

1 голос
/ 08 ноября 2019

Если вы хотите преобразовать timestamp в bigint, то вы можете сделать это следующим образом:

  • создать новый столбец, например bigint_date;
  • заполните его значениями bigint из текущего столбца timestamp_date;
  • удалите столбец timestamp_date;

Наборы изменений Liquibase могут выглядеть следующим образом:

<changeSet id="foo1" author="bar">
    <preConditions onFail="MARK_RAN">
        <not>
            <columnExists tableName="your_table" columnName="bigint_date"/>
        </not>
    </preConditions>
    <comment>Add new column</comment>
    <addColumn tableName="your_table">
        <column name="bigint_date" type="bigint(13)"/>
    </addColumn>
</changeSet>
<changeSet id="foo2" author="bar">
    <preConditions onFail="MARK_RAN">
        <columnExists tableName="your_table" columnName="bigint_date"/>
        <columnExists tableName="your_table" columnName="timestamp_date"/>
    </preConditions>
    <comment>Populate it with bigint values from your current "timestamp_date" column</comment>
    <update tableName="your_table">
        <column name="bigint_date" valueComputed="SELECT UNIX_TIMESTAMP(timestamp_date) FROM your_table"/>
    </update>
</changeSet>
<changeSet id="foo3" author="bar">
    <preConditions onFail="MARK_RAN">
        <columnExists tableName="your_table" columnName="timestamp_date"/>
    </preConditions>
    <comment>Drop your "timestamp_date" column</comment>
    <dropColumn tableName="your_table" columnName="timestamp_date"/>
</changeSet>
<changeSet id="foo4" author="bar">
    <preConditions onFail="MARK_RAN">
        <columnExists tableName="your_table" columnName="bigint_date"/>
    </preConditions>
    <comment>Update NULL values</comment>
    <update tableName="your_table">
        <column name="bigint_date" valueComputed="UNIX_TIMESTAMP()"/>
        <where>bigint_date IS NULL</where>
    </update>
</changeSet>
...