数据库Change Log
文件
自 Liquibase 2.0
起,Liquibase
包括支持普通 SQL
changelog
文件。这些changelog
可能包含在 XML
的changelog
中,并且可能包含任意 SQL
语句。语句将转换为自定义 sql
重构。
格式化的 SQL
文件使用注释为 Liquibase
提供元数据。每个 SQL
文件必须以以下注释开头:
--liquibase formatted sql
changeset
标签
changeSet
标签是你用来分组数据库更改的。每个changeSet
标签都由id
标签、author
标签和changelog
的classpath
名称的组合唯一标签。id
标签仅用作标识符,它不指示更改运行的顺序,甚至不一定是整数。如果您不知道或不希望保存实际作者,只需使用占位符值,如UNKNOW
。
当 Liquibase
执行数据库ChangeLog
时,它按顺序读取changeSet
,并针对每个changeSet
检查databasechangelog
表,以查看是否运行了 id/author/filepath
的组合。如果已运行,则将跳过changeSet
,除非存在真正的runAlways
标签。运行changeSet
中的所有更改后,Liquibase
将在databasechangelog
中插入带有 id/author/filepath
的新行以及changeSet
的MD5Sum
。
Liquibase
尝试执行每个changeSet
并在每次结束时提交事务,或者如果出现错误,则回滚。某些数据库将自动提交语句,这些语句会干扰此事务设置,并可能导致意外的数据库状态。因此,通常最好每个changeSet
只进行一次更改,除非有一组非自动提交更改要应用为事务(如插入数据)。
示例
格式化的 SQL
文件中的每个changeSet
都以注释形式开头
--changeset author:id attribute1:value1 attribute2:value2 [...]
changeset
注释后跟一个或多个 SQL
语句,用分号(或<endDelimiter>
属性的值)分隔。
可用属性
scriptComments
: 设置为true可以在sql执行之前移除所有注释,false则相反,默认为true。splitStatements
:设置为false时,在“s”和“go”上不会使用Liquibase 拆分语句,默认为true。endDelimiter
:设置语句结尾的分隔符。默认为";“可以设置为”"runAlways
:每次运行的时候都执行此changeSet,即使之前执行过。runOnChange
:在第一次看到更改时以及每次更改集更改时执行更改context
:如果在运行时传递了特定上下文,则执行更改。任何字符串都可用于上下文名称,并且它们处于不区分大小写状态。logicalFilePath
:用于在创建changeSet
的唯一标识符时覆盖文件名和路径。移动或重命名change logs
时是必需的。 --和下方重复,有点问题labels
:labels是将changeSet分到context的通用方法,但是与在运行时定义一组context,然后在changeSet中定义一个匹配表达式相反,是定义好context的一组labels后运行时匹配对应表达式。runInTransaction
:changeSet是否应作为单个事务运行(如果可能的情况)?默认为true。警告:注意这个属性。如果设置为false,并且在运行包含多个语句的changeSet的过程中发生错误,Liquibase DatabaseChangeLog表将使它们处于无效状态。failOnError
:如果在执行变更集时发生错误,是否认为此迁移失败?dbms
:要用于changSet
的数据库的类型。运行迁移步骤时,它会根据此属性检查数据库类型。
可用子标签
comment
:changeSet
的说明。XML
注释将提供相同的好处,Liquibase
的未来版本可能能够利用<comment>
标记注释来生成文档preConditions
:将执行changeSet
之前必须通过的前提条件。可用于在做不可恢复的内容(如自 1.7 起删除表)之前执行数据健全性检查<AnyRefactoringTag(s)>
:作为此changeSet
的一部分运行的数据库更改(称为重构)validCheckSum
:列出被认为对此更改有效的校验,而不考虑数据库中存储的内容。自 1.7 起,主要用于需要修改changeSet
,并且不希望在已运行过此修改的数据库上引发错误(不是建议的步骤)。rollback
:描述如何回滚changeSet
的 SQL 语句或重构标签
preconditions
标签
基于数据库状态的sql动态执行。
下面是使用preConditions
的几个原因:
- 记录更改日志的编写者在创建
changelog
时的假设。 - 强制使运行
change log
的用户不会违反这些假设 - 在执行不可恢复的更改(如
drop_Table
)之前执行数据检查 - 根据数据库的状态控制哪些
changeSet
运行
处理失败和错误
自 1.8 版本起,Liquibase
区分了preConditions
的"失败"(检查失败)和"错误"(在执行检查时引发的异常),并且可以通过<preConditions>
标签上的onFail
和onError
属性控制对两者的反应。
可用的属性
onFail
: 当proConditions
遇到失败的时候如何处理onError
:当proConditions
遇到错误的时候如何处理onUpdateSQL
:自版本1.9.5后当proConditions
遇到更新SQL
模型的时候如何处理onFailMessage
:自2.0起,在proConditions
失败时要输出的自定义消息。onErrorMessage
:在proConditions
错误时要输出的自定义消息。
onFail
或者onError
可能的取值
HALT
:立即停止执行整个changelog
。默认的值。CONTINUE
:跳过changeset
。将在下次更新时再次尝试执行changeset
。继续changelog
。MARK_RAN
:跳过changeset
,但将其标记为已执行。继续changelog
。WARN
:输出警告并继续正常执行changeset
/changelog
。
在changset
之外(例如,在changelog
的开头),可能的值只有 HALT
和 WARN
。
示例
可以为每个changeSet
指定preConditions
。目前,仅支持 SQL
检查preConditions
。
--preconditions onFail:HALT onError:HALT
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM my_table
rollback
标签
changset
可能包括回滚changeSet
时要应用的语句。回滚语句是窗体的注释
--rollback SQL STATEMENT
Change Log
示例
--liquibase formatted sql
--changeset hh:1
create table liquibase_test(
`id` int primary key,
`name` varchar(64) DEFAULT NULL
);
--rollback drop table liquibase_test;
--changeset hh:2
insert into liquibase_test(id, name) values (1, 'zhangsan');
--changeset hh:3
--preconditions onFail:CONTINUE onError:CONTINUE
--precondition-sql-check expectedResult:1 SELECT IF(COUNT(*) = 0,0,1) FROM `sys_user` WHERE REGION_CODE like '17%'
insert into liquibase_test(id, name) values (2, 'lisi');