Liquibase&;MySQL 5.7时间戳列修改问题
我有一个名为Liquibase&;MySQL 5.7时间戳列修改问题,mysql,liquibase,mysql-5.7,Mysql,Liquibase,Mysql 5.7,我有一个名为updated_time的列,它分配了时间戳数据类型: `updated_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 问题是,当前此列支持第二个精度。我需要它能够存储毫秒精度 因此,我准备了以下Liquibase变更集: { "databaseChangeLog": [ { "changeSet": { "id": "1", "changes": [
updated_time
的列,它分配了时间戳
数据类型:
`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版中对时间戳
数据类型进行了一些更改。默认情况下,我不能为时间戳
列分配非零(null)值。为了修复它,我必须对服务器配置本身进行一些更改。
让我们设想一下,我对服务器的访问权限有限,不能简单地修改配置,在Liquibase中是否有解决此问题的优雅方法?如果要将
时间戳
转换为bigint
,则可以通过以下方法进行:
- 创建一个新列,例如
李>bigint_date
- 用当前
列中的bigint值填充它李>timestamp\u date
- 删除
列李>timestamp\u date
<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>
添加新列
用当前“timestamp\u date”列中的bigint值填充它
删除“时间戳\日期”列
更新空值
bigint_日期为空
您是否尝试过使用日期时间(3)
而不是时间戳(3)
?不,我没有。时间戳更适合基于此线程:根据该线程-是。但你自己的需要呢?老实说,我需要那个专栏来存储时代价值。因此,我认为bigint
是最合适的。但我不知道如何在一个变更集中修改列的类型并将数据从timestamp
转换为bigint
。如果有办法的话,我会采用这种方法。否则,我会保留一个时间戳
。是的,我想你是对的,我正在裁剪这个变更集,但是是json。我很快就会回来报告。它工作正常,只剩下一件事:如何将新的bigint列的默认值设置为当前时间戳?有什么办法吗?在foo1
变更集的
标记中添加类似defaultValueComputed=“UNIX\u TIMESTAMP()”
的内容应该可以做到这一点选择时允许使用该功能,我尝试将其设置为默认值,没有问题,对吧。我的错。我已经用foo4
changeSet更新了我的答案。它将使用当前时间戳填充bigint\u date
的所有空值(如果有)。我想您必须在代码中填充bigint\u date
值,以便将来记录。