Как правильно использовать параметр liquibase `searchPath` для указания соответствующих папок ресурсов?

Я пытаюсь вызвать команду update для liquibase следующим образом:

liquibase update --changelog-file=./persistence/src/main/resources/changelog/db.changelog-dev.xml \
                 --url = "jdbc:postgresql://localhost:5432/sigma"

Это приводит к:

[...]
Starting Liquibase at 23:44:47 (version 4.17.2 #5255 built at 2022-11-01 18:07+0000)
Liquibase Version: 4.17.2
Liquibase Community 4.17.2 by Liquibase

Unexpected error running Liquibase: The file classpath:/changelog/db.changelog-master.xml was not found in the configured search path:
    - /Users/ikaerom/Dev/sigma-backend
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/liquibase-core.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/lib
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/jaybird.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/ojdbc8.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/snakeyaml.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/snowflake-jdbc.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/picocli.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/jaxb-runtime.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/jaxb-api.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/jaxb-core.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/hsqldb.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/connector-api.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/mssql-jdbc.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/h2.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/mariadb-java-client.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/liquibase-commercial.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/commons-lang3.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/postgresql.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/sqlite-jdbc.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/opencsv.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/commons-text.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/commons-collections4.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib/jcc.jar
    - /opt/homebrew/Cellar/liquibase/4.17.2/libexec/internal/lib
More locations can be added with the 'searchPath' parameter.

db.changelog-dev.xml, по сути, включает db.changelog-master.xml, который также ссылается на некоторые сценарии SQL. Два файла XML находятся в одной папке ресурсов $PROJECT_ROOT/persistence/src/main/resources/changelog. Все импортированные/включенные файлы SQL, указанные в XML-файле журнала изменений, находятся во вложенных папках папки ресурсов.

Любой способ указания этого ускользающего searchPath или даже --search-path параметра (как указано в документации ), кажется, эффектно терпит неудачу:

$> liquibase update --searchPath = "./persistence/src/main/resources/" --changelog-file=./persistence/src/main/resources/changelog/db.changelog-dev.xml --url = "jdbc:postgresql://localhost:5432/sigma"
Unexpected argument(s): --searchPath=./persistence/src/main/resources/

Итак, давайте попробуем другой указанный синтаксис:

$> liquibase update --search-path = "./persistence/src/main/resources/" --changelog-file=./persistence/src/main/resources/changelog/db.changelog-dev.xml --url = "jdbc:postgresql://localhost:5432/sigma"
Unexpected argument(s): --search-path=./persistence/src/main/resources/

Если я попытаюсь использовать LIQUIBASE_SEARCH_PATH=, я получу следующее:

[...]
Liquibase Version: 4.17.2
Liquibase Community 4.17.2 by Liquibase

Liquibase Community detected and ignored the following environment variables:
- LIQUIBASE_SEARCH_PATH
To configure Liquibase with environment variables requires a Liquibase Pro or Liquibase Labs license. Get a free trial at https://liquibase.com/trial. Options include the liquibase.licenseKey in the defaults file, adding a flag in the CLI, and more. Learn more at https://docs.liquibase.com.
[...]

Я действительно не хочу покупать профессиональную версию только для того, чтобы эта функция работала;).

Мой вопрос: как мне указать путь поиска для liquibase, чтобы подобрать его в моей оболочке bash?

Мне трудно поверить, что это не сработает, учитывая, что liquibase так хорошо задокументирован, и он всегда пытается дать вам правильные подсказки и указатели, если вы не используете его правильно. Что я упустил?

Обновление: у меня есть подозрение, что порядок вызова имеет значение. Итак, команда update должна быть последней в списке. Однако пока не повезло:

$> liquibase \
          --changelog-file=./persistence/src/main/resources/changelog/db.changelog-dev.xml \
          --url = "jdbc:postgresql://localhost:5432/sigma" \
          --searchpath = "./persistence/src/main/resources/changelog/" \
          update
[...]
Starting Liquibase at 14:29:51 (version 4.17.2 #5255 built at 2022-11-01 18:07+0000)
Liquibase Version: 4.17.2
Liquibase Community 4.17.2 by Liquibase

Unexpected error running Liquibase: The file ./persistence/src/main/resources/changelog/db.changelog-dev.xml was not found in the configured search path:
    - /Users/ikaerom/Dev/sigma-backend/persistence/src/main/resources/changelog
More locations can be added with the 'searchPath' parameter.

For more information, please use the --log-level flag
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
709
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение нашел сам, покопавшись в liquibase исходном коде.

В моем db.changelog-dev.xm у меня была строка, которая включала db.changelog-master.xml следующим образом. Этот classpath:/ должен быть удален:

-    <include file = "classpath:/changelog/db.changelog-master.xml"/>
+    <include file = "changelog/db.changelog-master.xml"/>

Затем этот вызов, наконец, работает (обратите внимание на адаптированный searchPath и относительное обозначение настроек параметра changelog):

    liquibase \
          --hub-mode=off \
          --headless=true \
          --url = "jdbc:postgresql://localhost:5432/sigma" \
          --searchPath = "./persistence/src/main/resources" \
          --changelog-file=changelog/db.changelog-dev.xml \
          update 2>&1 | grep -Ev -- "^##"

--hub-mode=off не позволит liquibase спрашивать, хотите ли вы подключиться к концентратору liquibase. Остальное - сахарная глазурь.

Единственная открытая проблема заключается в том, что когда liquibase вызывается из командной строки оболочки, пользователь, в конечном итоге владеющий таблицами журнала изменений/блокировок, является пользователем, вызывающим команду liquibase:

ikaerom@/tmp:sigma> \dt databasechangeloglock
+--------+-----------------------+-------+---------+
| Schema | Name                  | Type  | Owner   |
|--------+-----------------------+-------+---------|
| public | databasechangeloglock | table | ikaerom |
+--------+-----------------------+-------+---------+
SELECT 1
Time: 0.011s
ikaerom@/tmp:sigma> \dt databasechangeloglock
+--------+-----------------------+-------+---------+
| Schema | Name                  | Type  | Owner   |
|--------+-----------------------+-------+---------|
| public | databasechangeloglock | table | ikaerom |
+--------+-----------------------+-------+---------+
SELECT 1
Time: 0.010s

Однако, когда liquibase обновляется путем вызова загрузочного приложения Spring, то пользователем-владельцем таблицы является тот, который устанавливает контекст приложения (в моем случае сигма):

ikaerom@/tmp:sigma> \dt databasechangeloglock
+--------+-----------------------+-------+-------+
| Schema | Name                  | Type  | Owner |
|--------+-----------------------+-------+-------|
| public | databasechangeloglock | table | sigma |
+--------+-----------------------+-------+-------+
SELECT 1
Time: 0.010s
ikaerom@/tmp:sigma> \dt databasechangelog
+--------+-------------------+-------+-------+
| Schema | Name              | Type  | Owner |
|--------+-------------------+-------+-------|
| public | databasechangelog | table | sigma |
+--------+-------------------+-------+-------+
SELECT 1
Time: 0.009s

Это конфликтует, если вы сначала запустите обновление liquibase:

Caused by: liquibase.exception.DatabaseException: ERROR: relation "databasechangeloglock" already exists [Failed SQL: (0) CREATE TABLE public.databasechangeloglock (ID INTEGER NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP WITHOUT TIME ZONE, LOCKEDBY VARCHAR(255), CONSTRAINT databasechangeloglock_pkey PRIMARY KEY (ID))]
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:397)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:83)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:151)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:135)
    at liquibase.lockservice.StandardLockService.init(StandardLockService.java:115)
    at liquibase.lockservice.StandardLockService.acquireLock(StandardLockService.java:286)
    ... 94 common frames omitted
Caused by: org.postgresql.util.PSQLException: ERROR: relation "databasechangeloglock" already exists
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2675)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2365)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:355)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:490)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:408)
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:329)
    at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:315)
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:291)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:286)
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:94)
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:393)

Это опять же может быть решено правильным GRANT для сигмы или повторным назначением владельца законному пользователю. Или просто добавив свойство --username к имени контекста приложения весенней загрузки или владельца пользователя базы данных:

    liquibase \
          --hub-mode=off \
          --headless=true \
          --username = "sigma" \
          --url = "jdbc:postgresql://localhost:5432/sigma" \
          --searchPath = "./persistence/src/main/resources" \
          --changelog-file=changelog/db.changelog-dev.xml \
          update 2>&1 | grep -Ev -- "^##"

Другие вопросы по теме