使用
常见操作
清理
clean
默认应用于 模式数据库。它将删除 Neo4j-Migrations 相关的节点和关系。如果没有选择模式数据库,它将在可选的目标数据库上运行。如果没有配置,则将使用用户的 home 数据库。
清理操作将搜索
-
迁移链(这些节点包含有关已应用迁移的信息)
-
此 Neo4j-Migrations 的任何日志
-
Neo4j-Migrations 创建的任何约束
并将按顺序删除和删除它们。这是一个破坏性操作,因此请确保在至少思考两次的情况下不要将其应用于您的生产数据库。它不能通过 Neo4j-Migrations 撤消。
此操作接受一个布尔参数。当设置为 false
时,仅将当前配置的目标数据库的 迁移链 删除。当设置为 true
时,将删除 Neo4j-Migrations 创建的所有对象。
迁移 / 应用
migrate
命令(或其在迁移核心 API 中的底层方法 apply
)正是这样做的:它将所有本地解析的迁移应用于目标数据库,并将 已应用迁移链 存储在模式数据库中。
它返回最后应用的版本。
验证
validate
操作解析所有本地迁移,并检查所有迁移是否已按相同的顺序和相同的版本应用于配置的数据库。当所有迁移都已按正确的顺序应用时,目标数据库将被验证为有效,而在任何情况下,如果迁移缺失、未应用、以不同的顺序应用或以不同的校验和应用,则目标数据库将被验证为无效。
验证结果提供一个额外的操作 needsRepair()
。如果结果无效,您可以检查它是否需要修复。如果不是,您可以直接调用 apply 操作 将数据库变为有效状态。
CLI
请选择适合您操作系统或目标系统的 Neo4j-Migrations-CLI 版本,如 下载 中所述。在以下内容中,我们假设您下载并解压缩了与架构无关的版本。为了使该版本正常工作,您需要安装 JDK 17 或更高版本
java -version
curl -LO https://github.com/michael-simons/neo4j-migrations/releases/download/2.0.3/neo4j-migrations-2.0.3.zip
unzip neo4j-migrations-2.0.3.zip
cd neo4j-migrations-2.0.3
./bin/neo4j-migrations -V
这些命令应该首先打印您的 Java 版本,然后下载、解压缩并运行 Neo4j-Migrations-CLI 以提供其版本。
如果您只处理 基于 Cypher 的迁移 并且不需要任何 编程迁移,我们为您提供的平台提供了一个原生二进制文件,请确保选择它。它的启动时间更快,您不需要安装 JVM。 |
所有选项和参数
CLI 带有一个内置的帮助,可以通过 neo4j-migrations -h
或 neo4j-migrations --help
访问
./bin/neo4j-migrations --help
Usage: neo4j-migrations [-hvV] [--autocrlf] [--validate-on-migrate] -p
[=<password>] [-p[=<password>]]... [-a=<address>]
[-d=<database>] [--impersonate=<impersonatedUser>]
[--schema-database=<schemaDatabase>]
[--transaction-mode=<transactionMode>] [-u=<user>]
[--location=<locationsToScan>]...
[--package=<packagesToScan>]... [COMMAND]
Migrates Neo4j databases.
-a, --address=<address> The address this migration should connect to. The
driver supports bolt, bolt+routing or neo4j as
schemes.
--autocrlf Automatically convert Windows line-endings (CRLF)
to LF when reading resource based migrations,
pretty much what the same Git option does during
checkin.
-d, --database=<database> The database that should be migrated (Neo4j EE 4.0
+).
-h, --help Show this help message and exit.
--impersonate=<impersonatedUser>
The name of a user to impersonate during migration
(Neo4j EE 4.4+).
--location=<locationsToScan>
Location to scan. Repeat for multiple locations.
-p, --password[=<password>]
The password of the user connecting to the database.
--package=<packagesToScan>
Package to scan. Repeat for multiple packages.
--schema-database=<schemaDatabase>
The database that should be used for storing
information about migrations (Neo4j EE 4.0+).
--transaction-mode=<transactionMode>
The transaction mode to use.
-u, --username=<user> The login of the user connecting to the database.
-v Log the configuration and a couple of other things.
-V, --version Print version information and exit.
--validate-on-migrate Validating helps you verify that the migrations
applied to the database match the ones available
locally and is on by default.
Commands:
clean Removes Neo4j-Migration specific data from the selected
schema database
help Displays help information about the specified command
info Retrieves all applied and pending information, prints them
and exits.
init Creates a migration project inside the current folder.
migrate, apply Retrieves all pending migrations, verify and applies them.
run Resolves the specified migrations and applies them. Does not
record any metadata.
show-catalog Gets the local or remote catalog and prints it to standard
out in the given format.
validate Resolves all local migrations and validates the state of the
configured database with them.
如果 location
或 packages
均未给出值,我们将在当前工作目录中检查 neo4j/migrations
的目录结构,如果存在这样的结构,则将其用作 location
的默认值。
info
命令接受 mode
选项作为可选参数
Usage: neo4j-migrations info [mode=<mode>] Retrieves all applied and pending informations, prints them and exits. mode=<mode> Controls how the information should be computed. Valid options are COMPARE, LOCAL, REMOTE with COMPARE being the default. COMPARE will always compare locally discovered and remotely applied migrations, while the other options just check what's there.
这意味着我们默认情况下比较本地发现的内容与已应用于数据库的内容:我们检查缺失或多余的迁移,并比较校验和。有时,您可能只想快速查看数据库中的内容,而无需配置本地文件系统。在这种情况下,使用 mode=remote
:我们只查看数据库中的内容,并假设一切都已应用。使用 mode=local
打印出本地发现的内容以及当前设置,并将应用于空数据库。
neo4j-migrations 在当前工作目录中查找名为 .migration.properties 的属性文件,该文件可以包含所有支持的选项。使用此文件来避免重复每次长时间的命令行。使用 neo4j-migrations init 创建一个具有默认值的配置文件。传递给 neo4j-migrations 的任何选项都将在 init 命令之前存储。 |
CI/CD 使用中的安全密码
有 4 种方法可以指定密码
-
交互式:在没有参数的情况下使用
--password
,您的 shell 将提示您使用隐藏提示。 -
直接:使用
--password not-so-secret
。密码将在 shell 历史记录和进程监视器中可见。 -
通过环境变量:定义一个环境变量,如
MY_PASSWORD
,并使用--password:env MY_PASSWORD
。请注意,参数是变量的名称,而不是解析的值。 -
通过文件:在安全空间中创建一个文件,并在该文件中添加您的密码,并在该文件中使用一行,并使用
--password:file path/to/your/passwordFile
。密码将从此文件读取。
最后两种选项在脚本或 CI/CD 环境中是安全的选择。
众所周知的 Neo4j 环境变量
Neo4j AuraDB 在创建新的实例时提供 .env
文件,这些文件看起来像这样
# Wait 60 seconds before connecting using these details, or login to https://console.neo4j.io to validate the Aura Instance is available
NEO4J_URI=neo4j+s://xxxx.databases.neo4j.io
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=somepassword
AURA_INSTANCENAME=Instance01
Neo4j-Migrations 在存在时将识别这些环境变量。如果您没有为用户名、密码或地址指定值,并且这些变量存在且不为空,则 Neo4j-Migrations 将使用它们。
以上文件可以直接在这样的命令中使用(在 *Nix 系统上)
set -o allexport (1)
(source ~/Downloads/credentials-xxx.env; neo4j-migrations info)
set +o allexport
1 | 可能不需要在您的 shell 中 |
在您的 shell 中启用 Neo4j-Migrations 的自动完成功能
Neo4j-Migrations 可以生成一个 shell 脚本,为其在 Bash、zsh 和其他 shell 中的选项提供自动完成功能。以下是如何使用它
./bin/neo4j-migrations generate-completion > neo4j-migrations_completion.sh
然后可以通过 . neo4j-migrations_completion.sh
运行生成的脚本 neo4j-migrations_completion.sh
,也可以通过将其添加到 ~/.bashrc
或 ~/.zshrc
中永久安装。
如果您想在当前 shell 中拥有 Neo4j-Migrations 的自动完成功能,请使用以下命令
source <(./bin/neo4j-migrations generate-completion)
当您使用 Homebrew 时,macOS 的自动完成功能将自动安装。 |
完整示例
这是一个示例,它在 Java 包、其子包和基于 Cypher 的迁移的文件系统位置中查找迁移。在此示例中,我们已将包含 Java 基于迁移的目录导出为:export CLASSPATH_PREFIX=~/Projects/neo4j-migrations/neo4j-migrations-core/target/test-classes/
。请根据您的项目和/或需要进行调整。
此示例使用 info
命令告诉您哪些迁移已应用,哪些未应用
./bin/neo4j-migrations -uneo4j -psecret \
--location file:$HOME/Desktop/foo \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset1 \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset2 \
info
neo4j@localhost:7687 (Neo4j/4.4.0)
Database: neo4j
+---------+-----------------------------+--------+--------------+----+----------------+---------+--------------------------------------------------------------+
| Version | Description | Type | Installed on | by | Execution time | State | Source |
+---------+-----------------------------+--------+--------------+----+----------------+---------+--------------------------------------------------------------+
| 001 | FirstMigration | JAVA | | | | PENDING | a.s.n.m.c.t.changeset1.V001__FirstMigration |
| 002 | AnotherMigration | JAVA | | | | PENDING | a.s.n.m.c.t.changeset1.V002__AnotherMigration |
| 023 | NichtsIstWieEsScheint | JAVA | | | | PENDING | a.s.n.m.c.t.changeset2.V023__NichtsIstWieEsScheint |
| 023.1 | NichtsIstWieEsScheintNeu | JAVA | | | | PENDING | a.s.n.m.c.t.changeset2.V023_1__NichtsIstWieEsScheintNeu |
| 023.1.1 | NichtsIstWieEsScheintNeuNeu | JAVA | | | | PENDING | a.s.n.m.c.t.changeset2.V023_1_1__NichtsIstWieEsScheintNeuNeu |
| 030 | Something based on a script | CYPHER | | | | PENDING | V030__Something_based_on_a_script.cypher |
| 042 | The truth | CYPHER | | | | PENDING | V042__The_truth.cypher |
+---------+-----------------------------+--------+--------------+----+----------------+---------+--------------------------------------------------------------+
您可以重复 --package
和 --location
参数以进行细粒度控制。使用 migrate
应用迁移
./bin/neo4j-migrations -uneo4j -psecret \
--location file:$HOME/Desktop/foo \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset1 \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset2 \
migrate
[2022-05-31T11:25:29.894372000] Applied migration 001 ("FirstMigration").
[2022-05-31T11:25:29.985192000] Applied migration 002 ("AnotherMigration").
[2022-05-31T11:25:30.001006000] Applied migration 023 ("NichtsIstWieEsScheint").
[2022-05-31T11:25:30.016117000] Applied migration 023.1 ("NichtsIstWieEsScheintNeu").
[2022-05-31T11:25:30.032421000] Applied migration 023.1.1 ("NichtsIstWieEsScheintNeuNeu").
[2022-05-31T11:25:30.056182000] Applied migration 030 ("Something based on a script").
[2022-05-31T11:25:30.077719000] Applied migration 042 ("The truth").
Database migrated to version 042.
如果我们回到上面的 info
示例并再次获取所有迁移,我们会发现以下结果
./bin/neo4j-migrations -uneo4j -psecret \
--location file:$HOME/Desktop/foo \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset1 \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset2 \
info
Database: Neo4j/4.0.0@localhost:7687
+---------+-----------------------------+--------+-------------------------------+---------------+----------------+---------+--------------------------------------------------------------+
| Version | Description | Type | Installed on | by | Execution time | State | Source |
+---------+-----------------------------+--------+-------------------------------+---------------+----------------+---------+--------------------------------------------------------------+
| 001 | FirstMigration | JAVA | 2021-12-14T12:16:43.577Z[UTC] | msimons/neo4j | PT0S | APPLIED | a.s.n.m.c.t.changeset1.V001__FirstMigration |
| 002 | AnotherMigration | JAVA | 2021-12-14T12:16:43.876Z[UTC] | msimons/neo4j | PT0.032S | APPLIED | a.s.n.m.c.t.changeset1.V002__AnotherMigration |
| 023 | NichtsIstWieEsScheint | JAVA | 2021-12-14T12:16:43.993Z[UTC] | msimons/neo4j | PT0S | APPLIED | a.s.n.m.c.t.changeset2.V023__NichtsIstWieEsScheint |
| 023.1 | NichtsIstWieEsScheintNeu | JAVA | 2021-12-14T12:16:44.014Z[UTC] | msimons/neo4j | PT0S | APPLIED | a.s.n.m.c.t.changeset2.V023_1__NichtsIstWieEsScheintNeu |
| 023.1.1 | NichtsIstWieEsScheintNeuNeu | JAVA | 2021-12-14T12:16:44.035Z[UTC] | msimons/neo4j | PT0S | APPLIED | a.s.n.m.c.t.changeset2.V023_1_1__NichtsIstWieEsScheintNeuNeu |
| 030 | Something based on a script | CYPHER | 2021-12-14T12:16:44.093Z[UTC] | msimons/neo4j | PT0.033S | APPLIED | V030__Something_based_on_a_script.cypher |
| 042 | The truth | CYPHER | 2021-12-14T12:16:44.127Z[UTC] | msimons/neo4j | PT0.011S | APPLIED | V042__The truth.cypher |
+---------+-----------------------------+--------+-------------------------------+---------------+----------------+---------+--------------------------------------------------------------+
另一个 migrate
- 这次使用所有包 - 为我们提供了以下输出和结果
./bin/neo4j-migrations -uneo4j -psecret \
--location file:$HOME/Desktop/foo \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset1 \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset2 \
migrate
[2022-05-31T11:26:23.054169000] Skipping already applied migration 001 ("FirstMigration")
[2022-05-31T11:26:23.058779000] Skipping already applied migration 002 ("AnotherMigration")
[2022-05-31T11:26:23.059185000] Skipping already applied migration 023 ("NichtsIstWieEsScheint")
[2022-05-31T11:26:23.059504000] Skipping already applied migration 023.1 ("NichtsIstWieEsScheintNeu")
[2022-05-31T11:26:23.059793000] Skipping already applied migration 023.1.1 ("NichtsIstWieEsScheintNeuNeu")
[2022-05-31T11:26:23.060068000] Skipping already applied migration 030 ("Something based on a script")
[2022-05-31T11:26:23.060329000] Skipping already applied migration 042 ("The truth")
Database migrated to version 042.
数据库现在将处于有效状态
./bin/neo4j-migrations -uneo4j -psecret \
--location file:$HOME/Desktop/foo \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset1 \
--package ac.simons.neo4j.migrations.core.test_migrations.changeset2 \
validate
All resolved migrations have been applied to the default database.
使用 CLI 作为脚本运行器
CLI 也可以用作迁移脚本的简单运行器。唯一的要求是所有脚本都具有 此处 描述的格式的定义良好的名称
./bin/neo4j-migrations -uneo4j -psecret \
run \
--migration file:`pwd`/../../../neo4j-migrations-core/src/test/resources/manual_resources/V000__Create_schema.cypher \
--migration file:`pwd`/../../../neo4j-migrations-core/src/test/resources/manual_resources/V000__Create_graph.cypher \
--migration file:`pwd`/../../../neo4j-migrations-core/src/test/resources/manual_resources/V000__Refactor_graph.xml
[2022-09-27T17:24:11.589274000] Applied 000 ("Create graph")
[2022-09-27T17:24:11.860457000] Applied 000 ("Refactor graph")
Applied 2 migration(s).
您可以指定任意数量的资源。它们将按顺序应用。不会检查它们是否已应用或没有应用,也不会记录任何元数据。 |
基于 Java 的迁移模板
如上所述,这仅适用于 JVM 发行版。请按照以下步骤操作
curl -LO https://github.com/michael-simons/neo4j-migrations/releases/download/2.0.3/neo4j-migrations-2.0.3.zip
unzip neo4j-migrations-2.0.3.zip
cd neo4j-migrations-2.0.3
mkdir -p my-migrations/some/migrations
cat <<EOT >> my-migrations/some/migrations/V001__MyFirstMigration.java
package some.migrations;
import ac.simons.neo4j.migrations.core.JavaBasedMigration;
import ac.simons.neo4j.migrations.core.MigrationContext;
import org.neo4j.driver.Driver;
import org.neo4j.driver.Session;
public class V001__MyFirstMigration implements JavaBasedMigration {
@Override
public void apply(MigrationContext context) {
try (Session session = context.getSession()) {
}
}
}
EOT
javac -cp "lib/*" my-migrations/some/migrations/*
CLASSPATH_PREFIX=my-migrations ./bin/neo4j-migrations -v -uneo4j -psecret --package some.migrations info
我们在这里添加它以求完整性,但我们认为,基于 Java 的迁移最适合从您的应用程序内部进行,无论它是 Spring Boot、Quarkus 还是仅仅是一个普通的 Java 应用程序。CLI 应该主要被视为脚本运行器。 |
核心 API
我们在这里发布了 Java-API-Docs:Neo4j Migrations (Core) 2.0.3 API。请按照您喜欢的依赖项管理工具的说明获取核心 API,如 下载 中所述。
您将要使用的类是 ac.simons.neo4j.migrations.core.MigrationsConfig
及其相关的构建器和 ac.simons.neo4j.migrations.core.Migrations
,以及可能还有 ac.simons.neo4j.migrations.core.JavaBasedMigration
,如果您想进行编程重构。
配置和使用
配置主要由两部分组成:创建指向您数据库或集群的驱动程序实例,如 连接性部分 中所述,以及 MigrationsConfig
的实例。MigrationsConfig
的实例是通过流畅的构建器 API 创建的。将所有内容整合起来看起来像这样
Migrations
的实例Migrations migrations = new Migrations(
MigrationsConfig.builder()
.withPackagesToScan("some.migrations")
.withLocationsToScan(
"classpath:my/awesome/migrations",
"file:/path/to/migration"
)
.build(),
GraphDatabase.driver("bolt://:7687", AuthTokens.basic("neo4j", "secret"))
);
migrations.apply(); (1)
1 | 应用此迁移对象并迁移数据库 |
如果出现任何错误,API 将抛出一个 ac.simons.neo4j.migrations.core.MigrationsException
。当然,当您直接使用 API 时,您的迁移也将被记录为应用迁移的链(作为带有标签 __Neo4jMigration
的节点)。
以下操作可用
- info
-
返回有关上下文、数据库、所有已应用的应用和所有待处理的应用的信息
- apply
-
应用所有发现的迁移
- validate
-
根据已解析的迁移验证数据库
- clean
-
从由该工具创建的每个元数据中清理选定的模式数据库
相同的操作在 CLI 和 Maven-Plugin 中可用。相应的 Spring Boot 启动程序或 Quarkus 扩展程序将自动运行 apply
。
apply
有几个重载
-
当不带参数或带有单个布尔参数 i 时,它将应用所有发现的迁移
-
它将尝试解析 URL 到支持的迁移,并按原样应用它们,在使用一个或多个 URL 作为参数时不会写入元数据。此方法也可以通过 CLI 调用(通过
run
命令)。 -
当使用一个或多个
Refactoring
实例调用时,它将按顺序应用所有重构。此方法仅在 Core API 中可用。请在此处阅读更多信息:[applying-refactorings-programmatically]。
Spring-Boot-Starter
我们提供了一个启动器,它具有用于 Spring Boot 的自动配置。在您的 Spring Boot 应用程序中声明以下依赖项
<dependency>
<groupId>eu.michael-simons.neo4j</groupId>
<artifactId>neo4j-migrations-spring-boot-starter</artifactId>
<version>2.0.3</version>
</dependency>
或者按照 下载 中的 Gradle 说明进行操作。
启动器本身依赖于 Neo4j Java 驱动程序。驱动程序由 Spring Boot 自 2.4 版本开始管理,您可以直接通过 Spring Boot 使用配置支持。对于 Spring Boot 2.4 之前的 Spring Boot 版本,请查看此库的 0.0.13 版本。
Neo4j-Migrations 将自动在 classpath:neo4j/migrations
中查找迁移,如果此位置不存在,则会失败。它默认情况下不会扫描基于 Java 的迁移。
以下是如何配置驱动程序和迁移的示例
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret
spring.neo4j.uri=bolt://:7687
# Add configuration for your migrations, for example, additional packages to scan
org.neo4j.migrations.packages-to-scan=your.changesets, another.changeset
# Or disable the check if the location exists
org.neo4j.migrations.check-location=false
请查看 可用的配置属性,了解所有支持的属性。
启动器将记录有关产品版本和已连接数据库的一些详细信息。这可以通过将记录器 ac.simons.neo4j.migrations.core.Migrations.Startup 设置为高于 INFO 的级别来禁用。 |
与 @DataNeo4jTest
一起使用
如果您想将您的迁移与 @DataNeo4jTest
一起使用,后者由 Spring Boot 开箱即用提供,您必须手动导入我们的自动配置,如下所示
import ac.simons.neo4j.migrations.springframework.boot.autoconfigure.MigrationsAutoConfiguration;
import org.junit.jupiter.api.Test;
import org.neo4j.driver.Driver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.TestcontainersConfiguration;
@Testcontainers(disabledWithoutDocker = true)
@DataNeo4jTest (1)
@ImportAutoConfiguration(MigrationsAutoConfiguration.class) (2)
public class UsingDataNeo4jTest {
@Container
private static Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.4")
.withReuse(TestcontainersConfiguration.getInstance().environmentSupportsReuse()); (3)
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) { (4)
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
registry.add("spring.neo4j.authentication.username", () -> "neo4j");
registry.add("spring.neo4j.authentication.password", neo4j::getAdminPassword);
}
@Test
void yourTest(@Autowired Driver driver) {
// Whatever is tested
}
}
1 | 使用专用的 Neo4j 测试切片 |
2 | 导入 *此* 自动配置(不是 Spring Boot 的一部分) |
3 | 启动一个容器以进行测试 |
4 | 使用 DynamicPropertySource 动态配置测试资源 |
可用的配置属性
org.neo4j.migrations
命名空间中支持以下配置属性
org.neo4j.migrations.check-location
-
是否检查迁移脚本位置是否存在。
-
类型:
java.lang.Boolean
-
默认值:
true
-
org.neo4j.migrations.database
-
应该迁移的数据库(仅适用于 Neo4j EE 4.0+)。对于使用默认数据库,请保留
null
。-
类型:
java.lang.String
-
默认值:
null
-
org.neo4j.migrations.schema-database
-
应该用于存储有关迁移信息(仅适用于 Neo4j EE 4.0+)的数据库。对于使用默认数据库,请保留
null
。-
类型:
java.lang.String
-
默认值:
null
-
org.neo4j.migrations.impersonated-user
-
用于在迁移期间模拟的备用用户。可能具有比连接用户更高的权限,该权限将在迁移后再次被删除。需要 Neo4j EE 4.4+。对于使用连接的用户,请保留
null
。-
类型:
java.lang.String
-
默认值:
null
-
org.neo4j.migrations.enabled
-
是否启用 Neo4j-Migrations。
-
类型:
java.lang.Boolean
-
默认值:
true
-
org.neo4j.migrations.encoding
-
Cypher 迁移的编码。
-
类型:
java.nio.charset.Charset
-
默认值:
UTF-8
-
org.neo4j.migrations.installed-by
-
记录为
MIGRATED_TO
关系上的by
属性的用户名。-
类型:
java.lang.String
-
默认值:
系统用户
-
org.neo4j.migrations.locations-to-scan
-
迁移脚本的位置。
-
类型:
java.lang.String[]
-
默认值:
[classpath:neo4j/migrations]
-
org.neo4j.migrations.packages-to-scan
-
要扫描的 Java 迁移包列表。
-
类型:
java.lang.String[]
-
默认值:
[]
(空数组)
-
org.neo4j.migrations.transaction-mode
-
使用的交易模式(默认为“每次迁移”,这意味着一个脚本在一个交易中运行)。
-
类型:
TransactionMode
-
默认值:
PER_MIGRATION
-
org.neo4j.migrations.validate-on-migrate
-
验证有助于您验证应用于数据库的迁移与本地可用的迁移匹配,默认情况下启用。
-
类型:
java.lang.Boolean
-
默认值:
true
-
org.neo4j.migrations.autocrlf
-
在读取基于资源的迁移时自动将 Windows 行结尾(CRLF)转换为 LF,与 Git 选项在签入期间执行的操作基本相同。
-
类型:
java.lang.Boolean
-
默认值:
false
-
可以通过将 org.neo4j.migrations.enabled 设置为 false 来禁用迁移。 |
Quarkus
我们提供了一个扩展,它具有用于 Quarkus 的自动配置。在您的 Quarkus 应用程序中声明以下依赖项
<dependency>
<groupId>eu.michael-simons.neo4j</groupId>
<artifactId>neo4j-migrations-quarkus</artifactId>
<version>2.0.3</version>
</dependency>
该扩展本身依赖于 Neo4j Java 驱动程序 和相应的 Quarkus 扩展程序 Quarkus-Neo4j,并且需要至少 Quarkus 2.6。您不需要声明这些依赖项,它们已经是此扩展的传递依赖项。
Neo4j-Migrations 将自动在 classpath:neo4j/migrations
中查找迁移,如果此位置不存在,则会失败。它默认情况下不会扫描基于 Java 的迁移。
以下是如何配置驱动程序和迁移的示例
quarkus.neo4j.uri=bolt://:7687
quarkus.neo4j.authentication.username=neo4j
quarkus.neo4j.authentication.password=secret
org.neo4j.migrations.packages-to-scan=foo.bar
如果您通过 org.neo4j.migrations.enabled
禁用 Neo4j-Migrations,我们不会在启动时应用迁移,但 Migrations
对象仍将在上下文中使用。
对于 Spring-Boot-Starter 可用的所有其他属性,也适用于 Quarkus 扩展程序。它们的命名空间相同:org.neo4j.migrations 。该模块还将记录有关产品版本和已连接数据库的一些详细信息。这可以通过将记录器 ac.simons.neo4j.migrations.core.Migrations.Startup 设置为高于 INFO 的级别来禁用。 |
构建时与运行时配置
org.neo4j.migrations.packages-to-scan
和 org.neo4j.migrations.locations-to-scan
是构建时配置选项,无法在运行时更改。这允许创建优化的镜像:所有属于类路径(脚本和基于类的迁移)的迁移在镜像构建时已被发现,并且包含在镜像本身中(这适用于本机镜像和 JVM 镜像)。
虽然文件系统位置(所有以 file://
开头的 location)中的脚本仍然在运行时被发现,因此允许添加脚本而无需重新创建应用程序镜像,但 location 无法动态更改。如果您需要动态的 file://
位置,请使用 org.neo4j.migrations.external-locations
。此属性可以在运行时更改,并允许一个镜像用于不同的部署,这些部署指向类路径外部不同脚本的不同外部 location
另一种方法是在 sidecar 容器中使用 CLI,指向动态 location 并保持在应用程序本身之外应用数据库迁移。
Dev Services 集成
Neo4j-Migrations 将在 Quarkus Dev UI 中的 https://:8080/q/dev/ 下显示为一个图块。它提供了一个 迁移列表,可用于清理数据库或应用所有迁移。当在启动时禁用迁移或存在可能重置或重新创建测试数据的回调时,后者非常有用。
Maven-Plugin
您可以从构建中使用 Maven-Plugin 触发 Neo4j-Migrations。有关所有目标和配置选项的详细列表,以及插件的默认生命周期映射,请参阅专门的 Maven-Plugin 页面。
配置
大多数情况下,您将为插件配置以下属性
<plugin>
<groupId>eu.michael-simons.neo4j</groupId>
<artifactId>neo4j-migrations-maven-plugin</artifactId>
<version>2.0.3</version>
<executions>
<execution>
<configuration>
<user>neo4j</user>
<password>secret</password>
<address>bolt://:${it-database-port}</address>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
所有目标都提供这些属性。默认情况下,插件将在 neo4j/migrations
中查找 基于 Cypher 的迁移。您可以通过 locationsToScan
在 configuration
元素中进行更改,如下所示
<locationsToScan>
<locationToScan>file://${project.build.outputDirectory}/custom/path</locationToScan>
</locationsToScan>
添加多个 locationToScan
元素以扫描多个位置。
定义和使用目录
本章主要介绍使用基于目录的迁移可以实现的概念性用法或场景。除了轻松地将本地或远程目录作为 XML 或 Cypher 文件转储外,所有场景都可以使用之前解释过的任何 API 执行,无论是 CLI、Core API 还是 Spring Boot、Quarkus 或 Maven 中的 API。
目录是一种强大的机制,可以按照您的意愿塑造数据库的模式,这只是可以实现的众多可能场景中的一小部分。
在接下来的步骤中,我们假设您正在使用 CLI 并使用 init
命令创建了一个本地目录结构,其中包含连接数据(如 URL 和凭据)以及您的迁移。
neo4j-migrations -a bolt://:7687 -u neo4j -p secret init
tree -a
这将导致
.
├── .migrations.properties
└── neo4j
└── migrations
2 directories, 1 file
我们将要使用的所有迁移都将存储在 neo4j/migrations
中。
在对模式进行任何操作之前,一个明智的步骤是断言我们的本地目录符合预期的远程目录。在本例中,我们断言远程目录为空,并将第一个迁移定义为:
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="https://michael-simons.github.io/neo4j-migrations">
<verify useCurrent="true"/> (1)
</migration>
1 | useCurrent 已设置为 true ,以引用版本 10 中定义的本地目录,该目录为空,这正是我们所期望的。 |
现在通过 neo4j-migrations apply
应用它会产生以下结果:
[2022-06-01T15:13:39.997000000] Applied migration 010 ("Assert empty schema").
Database migrated to version 010.
当然,此步骤只执行一次,即在应用此迁移时。如果我们再添加另一个迁移,则不会再次进行验证,因为 010 已经应用。因此,可以将一个验证步骤添加到每个基于目录的迁移中。
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="https://michael-simons.github.io/neo4j-migrations">
<catalog>
<constraints>
<constraint name="person_name_unique" type="unique">
<label>Person</label>
<properties>
<property>name</property>
</properties>
</constraint>
</constraints>
</catalog>
<verify/>
<create ref="person_name_unique"/>
</migration>
请注意,我们没有在这里指定 useCurrent
。这意味着验证应该基于版本 020 之前的本地目录进行。应用此迁移会产生:
[2022-06-01T15:17:27.508000000] Skipping already applied migration 010 ("Assert empty schema")
[2022-06-01T15:17:27.771000000] Applied migration 020 ("Create person name unique").
Database migrated to version 020.
一天后,您发现对人名进行唯一约束并不是最好的主意,于是您决定修复它。假设为了理智起见,每个人都有一个名字,我们将这种唯一性替换为存在约束。
存在约束是 Neo4j 企业版的功能,因此我们也必须对其进行处理,并且为下一个版本定义了两个不同的文件。
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="https://michael-simons.github.io/neo4j-migrations">
<?assume that edition is community ?>
<drop item="person_name_unique"/>
</migration>
对于企业版,我们可以像这样重新定义约束:
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="https://michael-simons.github.io/neo4j-migrations">
<?assume that edition is enterprise ?>
<catalog>
<constraints>
<constraint name="person_name_unique" type="exists">
<label>Person</label>
<properties>
<property>name</property>
</properties>
</constraint>
</constraints>
</catalog>
<drop ref="person_name_unique"/>
<create ref="person_name_unique"/>
</migration>
请注意,我们如何在 清单 15 中通过 ref refer
到约束,以及如何在 清单 14 中使用 item
。这样做的原因是在社区版迁移中,我们只引用了旧的项目。我们在企业版脚本中重新定义了项目,因此我们不妨引用它。在不支持约束名称的旧版 Neo4j 中,Neo4j-Migrations 将使用旧的定义来删除所讨论的项目。
现在应用当前状态会产生:
[2022-06-01T16:04:46.446188000] Skipping 030 ("Fix person name constraint CE") due to unmet preconditions:
// assume that edition is COMMUNITY
[2022-06-01T16:04:46.493400000] Skipping already applied migration 010 ("Assert empty schema")
[2022-06-01T16:04:46.496401000] Skipping already applied migration 020 ("Create person name unique")
[2022-06-01T16:04:46.659585000] Applied migration 030 ("Fix person name constraint EE").
Database migrated to version 030.
假设您在以下清单中有一些其他与企业相关的项目:
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="https://michael-simons.github.io/neo4j-migrations">
<?assume that edition is enterprise ?>
<catalog>
<indexes/>
<constraints>
<constraint name="liked_day" type="exists">
<type>LIKED</type>
<properties>
<property>day</property>
</properties>
</constraint>
<constraint name="person_keys" type="key">
<label>Person</label>
<properties>
<property>firstname</property>
<property>surname</property>
</properties>
</constraint>
</constraints>
</catalog>
<create ref="liked_day"/>
<create ref="person_keys"/>
</migration>
要获取有关数据库的信息,您可以检查远程目录。
neo4j-migrations show-catalog
它将以 XML 格式打印目录。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<migration xmlns="https://michael-simons.github.io/neo4j-migrations">
<catalog>
<indexes/>
<constraints>
<constraint name="liked_day" type="unique">
<label>LIKED</label>
<properties>
<property>day</property>
</properties>
</constraint>
<constraint name="person_keys" type="key">
<label>Person</label>
<properties>
<property>firstname</property>
<property>surname</property>
</properties>
</constraint>
<constraint name="person_name_unique" type="exists">
<label>Person</label>
<properties>
<property>name</property>
</properties>
</constraint>
</constraints>
</catalog>
</migration>
您也可以使用以下命令获取 Cypher 格式的目录:
neo4j-migrations show-catalog format=CYPHER version=4.4
产生:
CREATE CONSTRAINT person_keys IF NOT EXISTS FOR (n:Person) REQUIRE (n.firstname, n.surname) IS NODE KEY;
CREATE CONSTRAINT liked_day IF NOT EXISTS FOR ()-[r:LIKED]-() REQUIRE r.day IS NOT NULL;
CREATE CONSTRAINT person_name_unique IF NOT EXISTS FOR (n:Person) REQUIRE n.name IS NOT NULL;
将版本号更改为较旧的版本也会给出正确的语法。
> neo4j-migrations show-catalog format=CYPHER version=3.5
CREATE CONSTRAINT ON (n:Person) ASSERT (n.firstname, n.surname) IS NODE KEY;
CREATE CONSTRAINT ON ()-[r:LIKED]-() ASSERT exists(r.day);
CREATE CONSTRAINT ON (n:Person) ASSERT exists(n.name);
毕竟,您决定最好不要对人名进行任何约束,并将您的实验也删除。您可以使用 <apply />
使您的数据库看起来完全像您的目录。但这也会包含所有先前定义的项目。
因此,您需要重置目录,如以下清单所示:
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="https://michael-simons.github.io/neo4j-migrations">
<catalog reset="true">
<constraints>
<constraint name="unique_person_id" type="unique">
<label>Person</label>
<properties>
<property>id</property>
</properties>
</constraint>
</constraints>
</catalog>
<apply/>
</migration>
然后进行最终验证。
<?xml version="1.0" encoding="UTF-8"?>
<migration xmlns="https://michael-simons.github.io/neo4j-migrations">
<verify allowEquivalent="false"/>
</migration>
运行以下命令查看结果:
neo4j-migrations apply
应用所有内容
[2022-06-01T19:16:20.058218000] Skipping 030 ("Fix person name constraint CE") due to unmet preconditions:
// assume that edition is COMMUNITY
[2022-06-01T19:16:20.223937000] Skipping already applied migration 010 ("Assert empty schema")
[2022-06-01T19:16:20.225464000] Skipping already applied migration 020 ("Create person name unique")
[2022-06-01T19:16:20.225748000] Skipping already applied migration 030 ("Fix person name constraint EE")
[2022-06-01T19:16:20.226022000] Skipping already applied migration 040 ("Additional stuff")
[2022-06-01T19:16:20.501686000] Applied migration 050 ("A new start").
[2022-06-01T19:16:20.551983000] Applied migration 060 ("Assert final state").
Database migrated to version 060.
neo4j-migrations show-catalog format=CYPHER
将远程目录呈现为
CREATE CONSTRAINT unique_person_id IF NOT EXISTS FOR (n:Person) REQUIRE n.id IS UNIQUE;
本地目录也是如此
neo4j-migrations show-catalog format=CYPHER mode=LOCAL 2&>/dev/null
这里包含重定向,以便跳过 stderr 上的日志消息(关于由于不满足先决条件而跳过一个迁移的消息)。
此页面对您有帮助吗?