Neo4j Labs has released Neo4j Migrations, a database migration and refactoring tool that offers version control for relational databases. Inspired by FlywayDB, Neo4j Migrations depends on the Neo4j Java Driver and ClassGraph which is used to detect migrations on the classpath.
This tool may be used as a CLI via the neo4j-migrations
command, after downloading the CLI binary from the GitHub releases page. Binaries are available for both Windows and Unix-like operating systems. Homebrew offers an installation for macOS:
brew install michael-simons/homebrew-neo4j-migrations/neo4j-migrations
A JVM-based version is also available for download and it’s the only one supporting Java-based migrations with the --package
argument.
Neo4j Migrations offers two options to apply migrations or any other changes to Neo4j. Cypher-based migrations are written down as Cypher statements, where a ‘;
’ separates each statement. The .cypher
files in classpath:neo4j/migrations
are automatically detected and each file is executed in a single transaction. Other locations on the classpath or filesystem may be specified as follows:
MigrationsConfig configLookingAtDifferentPlaces = MigrationsConfig.builder()
.withLocationsToScan(
"classpath:[custompath]",
"file:/[custompath]"
).build();
Alternatively, Java-based migrations may be used, which offer more flexibility as Java logic can be used to change anything in the database by implementing the JavaBasedMigration
interface:
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 CustomMigration implements JavaBasedMigration {
@Override
public void apply(MigrationContext context) {
try (Session session = context.getSession()) {
…
}
}
}
A Maven plugin is available to trigger the database migration via the build, instead of using the CLI, by supplying the following configuration:
<plugin>
<groupId>eu.michael-simons.neo4j</groupId>
<artifactId>neo4j-migrations-maven-plugin</artifactId>
<version>[version]</version>
<executions>
<execution>
<id>migrate</id>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<user>[username]</user>
<password>[password]</password>
<address>[address]</address>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
The plugin automatically detects the migrations within neo4j/migrations
. Other directories may be specified with:
<locationsToScan>
<locationToScan>file://${project.build.outputDirectory}/[custom-path]</locationToScan>
</locationsToScan>
Alternatively, the Spring Boot starter may be used to trigger the migration by configuring the dependency:
<dependency>
<groupId>eu.michael-simons.neo4j</groupId>
<artifactId>neo4j-migrations-spring-boot-starter</artifactId>
<version>[version]</version>
</dependency>
The starter uses the Neo4j Java Driver which can be configured directly when using Spring Boot 2.4 or newer. The starter doesn’t scan by default for Java-based migrations and uses classpath:neo4j/migrations
as the default directory for Cypher statements. Various properties are available to configure the starter, such as:
spring.neo4j.authentication.username=[username]
spring.neo4j.authentication.password=[location]
spring.neo4j.uri=[uri]
# To configure additional locations with migrations
org.neo4j.migrations.packages-to-scan=location1, location2
Spring Boot supports Neo4j tests with the @DataNeo4jTest
annotation and can be used together with the migrations by supplying the following configuration:
@Testcontainers(disabledWithoutDocker = true)
@DataNeo4jTest
@ImportAutoConfiguration(MigrationsAutoConfiguration.class)
public class CustomTest {
@Container
private static Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.2")
.withReuse(TestcontainersConfiguration.getInstance().environmentSupportsReuse());
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
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) {
…
}
}
Sebastian Daschner explains in his blog and the accompanying video how the CLI may be used to migrate Neo4j graph schemas in Kubernetes by using init containers.
The complete documentation including all the configuration options is available on GitHub and also contains several example projects.