BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Migrating Neo4j Graph Schemas with Neo4j Migrations

Migrating Neo4j Graph Schemas with Neo4j Migrations

This item in japanese

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.

Rate this Article

Adoption
Style

BT