Я пытаюсь вызвать команду 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
Решение нашел сам, покопавшись в 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 -- "^##"