Using Liquibase MongoDB

Liquibase 是一个用于数据库架构更改管理的开源工具,它允许通过 MongoDB Extension 管理 MongoDB 数据库。

Liquibase is an open source tool for database schema change management, it allows managing MongoDB databases via it’s MongoDB Extension.

Quarkus 提供一级支持以使用 Liquibase MongoDB 扩展,本指南对此进行了解释。

Quarkus provides first class support for using Liquibase MongoDB Extension as will be explained in this guide.

Solution

我们建议您遵循接下来的部分中的说明,按部就班地创建应用程序。然而,您可以直接跳到完成的示例。

We recommend that you follow the instructions in the next sections and create the application step by step. However, you can go right to the completed example.

克隆 Git 存储库: git clone {quickstarts-clone-url},或下载 {quickstarts-archive-url}[存档]。

Clone the Git repository: git clone {quickstarts-clone-url}, or download an {quickstarts-archive-url}[archive].

解决方案位于 liquibase-mongodb-quickstart directory

The solution is located in the liquibase-mongodb-quickstart directory.

Setting up support for Liquibase

若要开始将 Liquibase MongoDB 扩展与您的项目一起使用,您只需:

To start using the Liquibase MongoDB Extension with your project, you just need to:

  • add your changeLog to the src/main/resources/db/changeLog.xml file as you usually do with Liquibase

  • activate the migrate-at-start option to migrate the schema automatically or inject the Liquibase object and run your migration as you normally do.

您可以通过在项目基本目录中运行以下命令将 liquibase-mongodb 扩展添加到您的项目中:

You can add the liquibase-mongodb extension to your project by running the following command in your project base directory:

Unresolved directive in liquibase-mongodb.adoc - include::{includes}/devtools/extension-add.adoc[]

这会将以下内容添加到构建文件中:

This will add the following to your build file:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-liquibase-mongodb</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-liquibase-mongodb")

Liquibase MongoDB 扩展支持依赖于 Quarkus MongoDB 客户端配置。目前,它不支持多个客户端。您需要将 MongoDB 配置添加到 application.properties 文件中,以便允许 Liquibase 管理架构。

The Liquibase MongoDB extension support relies on the Quarkus MongoDB client config. For the time being, it does not support multiple clients. You need to add the MongoDB config to the application.properties file in order to allow Liquibase to manage the schema.

以下是 application.properties 文件的一个示例:

The following is an example for the application.properties file:

# configure MongoDB
quarkus.mongodb.connection-string = mongodb://localhost:27017

# Liquibase MongoDB minimal config properties
quarkus.liquibase-mongodb.migrate-at-start=true

# Liquibase MongoDB optional config properties
# quarkus.liquibase-mongodb.change-log=db/changeLog.xml
# quarkus.liquibase-mongodb.validate-on-migrate=true
# quarkus.liquibase-mongodb.clean-at-start=false
# quarkus.liquibase-mongodb.contexts=Context1,Context2
# quarkus.liquibase-mongodb.labels=Label1,Label2
# quarkus.liquibase-mongodb.default-catalog-name=DefaultCatalog
# quarkus.liquibase-mongodb.default-schema-name=DefaultSchema

Liquibase MongoDB 使用连接字符串进行配置,我们会尽力构建与 MongoDB 客户端配置匹配的连接字符串,但如果某些配置属性不起作用,您可以考虑将它们直接添加到 quarkus.mongodb.connection-string 配置属性中。

Liquibase MongoDB is configured using a connection string, we do our best to craft a connection string that matches the MongoDB client configuration but if some configuration properties are not working you may consider adding them directly into the quarkus.mongodb.connection-string config property.

根据 Liquibase 命名约定,将 changeLog 文件添加到默认文件夹中:changeLog 支持 `src/main/resources/db/changeLog.xml`YAML、JSON 和 XML 格式。

Add a changeLog file to the default folder following the Liquibase naming conventions: src/main/resources/db/changeLog.xml YAML, JSON and XML formats are supported for the changeLog.

<?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"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <changeSet id="1" author="loic">
        <ext:createCollection collectionName="Fruit"/>

        <ext:createIndex collectionName="Fruit">
            <ext:keys>{color: 1}</ext:keys>
            <ext:options>{name: "colorIdx"}</ext:options>
        </ext:createIndex>

        <ext:insertOne collectionName="Fruit">
            <ext:document>{"name":"orange", "color": "orange"}</ext:document>
        </ext:insertOne>
    </changeSet>

</databaseChangeLog>

现在可以启动应用程序,然后 Quarkus 会根据配置运行 Liquibase 的更新方法。

Now you can start your application and Quarkus will run the Liquibase’s update method according to your config.

Using the Liquibase object

如果你有兴趣直接使用 Liquibase 对象,你可以按如下方式注入它:

In case you are interested in using the Liquibase object directly, you can inject it as follows:

如果你启用了 quarkus.liquibase.migrate-at-start 属性,那么当你在使用 Liquibase 实例时,Quarkus 已经运行了迁移操作。

If you enabled the quarkus.liquibase.migrate-at-start property, by the time you use the Liquibase instance, Quarkus will already have run the migrate operation.

import io.quarkus.liquibase.LiquibaseFactory;

@ApplicationScoped
public class MigrationService {
    // You can Inject the object if you want to use it manually
    @Inject
    LiquibaseMongodbFactory liquibaseMongodbFactory; 1

    public void checkMigration() {
        // Use the liquibase instance manually
        try (Liquibase liquibase = liquibaseFactory.createLiquibase()) {
            liquibase.dropAll(); 2
            liquibase.validate();
            liquibase.update(liquibaseFactory.createContexts(), liquibaseFactory.createLabels());
            // Get the list of liquibase change set statuses
            List<ChangeSetStatus> status = liquibase.getChangeSetStatuses(liquibaseFactory.createContexts(), liquibaseFactory.createLabels()); 3
        }
    }
}
1 Inject the LiquibaseFactory object
2 Use the Liquibase instance directly
3 List of applied or not applied liquibase ChangeSets

Liquibase Mongodb on Kubernetes

有时,最好不要在每次应用程序启动时执行 Liquibase 初始化。一个这样的例子是在 Kubernetes 上部署,在 Kubernetes 上每个副本执行 Liquibase 没有意义。相反,最好执行它一次,然后在没有 Liquibase 的情况下启动实际应用程序。为了支持这种用例,当为 Kubernetes 生成清单时,生成的清单包含 Liquibase 的 Kubernetes 初始化 JobJob 执行初始化,实际 Pod 将在 Job 成功完成后启动。

Sometimes, it’s helpful not to execute Liquibase initialization on each application startup. One such example is when deploying on Kubernetes, where it doesn’t make sense to execute Liquibase on every single replica. Instead it’s desirable to execute it once and then start the actual application without Liquibase. To support this use case, when generating manifests for Kubernetes the generated manifests contain a Kubernetes initialization Job for Liquibase. The Job performs initialization and the actual Pod, will starts once the Job is successfully completed.

Disabling

此功能默认启用,可以使用以下内容进行全局禁用:

The feature is enabled by default and can be globally disabled, using:

quarkus.kubernetes.init-task-defaults.enabled=false

或在 OpenShift 上:

or on OpenShift:

quarkus.openshift.init-task-defaults.enabled=false

Using a custom image that controls waiting for the Job

若要更改默认`groundnuty/k8s-wait-for:no-root-v1.7` 的 wait-for 图像,可以使用:

To change the wait-for image which by default is groundnuty/k8s-wait-for:no-root-v1.7 you can use:

quarkus.kubernetes.init-task-defaults.wait-for-container.image=my/wait-for-image:1.0

或在 OpenShift 上:

or on OpenShift:

quarkus.openshift.init-task-defaults.wait-for-container.image=my/wait-for-image:1.0

Note: 在此上下文中,全局意味着 for all extensions that support init task externalization.

Note: In this context globally means for all extensions that support init task externalization.

Configuration Reference

Unresolved directive in liquibase-mongodb.adoc - include::{generated-dir}/config/quarkus-liquibase-mongodb.adoc[]