Skip to content

Commit 3041006

Browse files
committed
Add JSON reading / writing support
1 parent 03b6971 commit 3041006

23 files changed

Lines changed: 1658 additions & 137 deletions

README.adoc

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
image:https://github.com/nmervaillie/neo4j-db-copy/actions/workflows/ci.yml/badge.svg["CI", link="https://github.com/nmervaillie/neo4j-db-copy/actions/workflows/ci.yml"]
44

5-
A development tool useful to copy the data from a Neo4j database to another Neo4j database.
5+
A development tool useful to copy the data from a Neo4j database to another Neo4j database, or to and from a JSONL file.
66
Databases can be local or remote.
7-
As the copy is done through the Neo4j driver, no admin access to Neo4j is required.
7+
As the copy is done through the Neo4j driver or a local JSONL export, no admin access to Neo4j is required.
88

99
This is useful to copy things around, for example test/reference data from an environment to another.
1010

@@ -24,15 +24,15 @@ The resulting app can be found in the `target` directory.
2424

2525
[source,bash]
2626
----
27-
Usage: neo4j-db-copy [-hV] [-lock] -sp -tp -sa=<sourceAddress>
28-
-sd=<sourceDatabase> [-su=<sourceUserName>]
29-
-ta=<targetAddress> -td=<targetDatabase>
27+
Usage: neo4j-db-copy [-hV] [-lock] -sa=<sourceAddress>
28+
[-sd=<sourceDatabase>] [-sp] [-su=<sourceUserName>]
29+
-ta=<targetAddress> [-td=<targetDatabase>] [-tp]
3030
[-tu=<targetUserName>] [-enp=<excludeNodeProperties>[,
3131
<excludeNodeProperties>...]]...
3232
[-erp=<excludeRelationshipProperties>[,
3333
<excludeRelationshipProperties>...]]...
34-
Copy the content of a Neo4j database to another Neo4j database, via the
35-
network, through the bolt protocol.
34+
Copy the content of a Neo4j database to another Neo4j database, or to/from a
35+
JSONL file.
3636
-enp, --exclude-node-properties=<excludeNodeProperties>[,
3737
<excludeNodeProperties>...]
3838
Comma-separated list of node properties to exclude from the
@@ -44,22 +44,62 @@ network, through the bolt protocol.
4444
-h, --help Show this help message and exit.
4545
-lock, --lock-source-database
4646
Set the source database to read-only mode before copying
47+
(only valid for bolt/neo4j source)
4748
-sa, --source-address=<sourceAddress>
48-
The source database address (ex: neo4j+s://my-server:7687)
49+
The source address: bolt/neo4j URI for Neo4j, or
50+
file:///path/to/file.jsonl for JSONL
4951
-sd, --source-database=<sourceDatabase>
50-
The source database to connect to.
52+
The source database to connect to (used only for bolt/neo4j
53+
URIs).
5154
-sp, --source-password
52-
The source database password to connect with
55+
The source database password to connect with (used only for
56+
bolt/neo4j URIs)
5357
-su, --source-username=<sourceUserName>
54-
The source database username to connect as (default: neo4j)
58+
The source database username to connect as (default: neo4j,
59+
used only for bolt/neo4j URIs)
5560
-ta, --target-address=<targetAddress>
56-
The target database address (ex: neo4j+s://my-server:7687)
61+
The target address: bolt/neo4j URI for Neo4j, or
62+
file:///path/to/file.jsonl for JSONL
5763
-td, --target-database=<targetDatabase>
58-
The target database to connect to.
64+
The target database to connect to (used only for bolt/neo4j
65+
URIs).
5966
-tp, --target-password
60-
The target database password to connect with
67+
The target database password to connect with (used only for
68+
bolt/neo4j URIs)
6169
-tu, --target-username=<targetUserName>
62-
The target database username to connect as (default: neo4j)
70+
The target database username to connect as (default: neo4j,
71+
used only for bolt/neo4j URIs)
6372
-V, --version Print version information and exit.
6473
----
6574

75+
Bolt credentials and database names are required only for bolt/neo4j endpoints.
76+
`file:` endpoints are local JSONL files and do not use Neo4j credentials.
77+
78+
The JSON export format is JSONL: one JSON object per line.
79+
Files ending in `.gz` are read and written as gzip-compressed JSONL.
80+
Only `file:` URIs are supported for JSON import/export.
81+
82+
Examples:
83+
84+
[source,bash]
85+
----
86+
# Neo4j -> Neo4j
87+
neo4j-db-copy \
88+
-sa neo4j+s://source.example:7687 -su neo4j -sp -sd sourcedb \
89+
-ta neo4j+s://target.example:7687 -tu neo4j -tp -td targetdb
90+
91+
# Neo4j -> JSONL
92+
neo4j-db-copy \
93+
-sa neo4j+s://source.example:7687 -su neo4j -sp -sd sourcedb \
94+
-ta file:///tmp/export.jsonl
95+
96+
# Neo4j -> compressed JSONL
97+
neo4j-db-copy \
98+
-sa neo4j+s://source.example:7687 -su neo4j -sp -sd sourcedb \
99+
-ta file:///tmp/export.jsonl.gz
100+
101+
# compressed JSONL -> Neo4j
102+
neo4j-db-copy \
103+
-sa file:///tmp/export.jsonl.gz \
104+
-ta neo4j+s://target.example:7687 -tu neo4j -tp -td targetdb
105+
----

pom.xml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<jreleaser.version>1.13.1</jreleaser.version>
5050
<mockito-core.version>5.23.0</mockito-core.version>
5151
<assertj-core.version>4.0.0-M1</assertj-core.version>
52+
<jackson.version>2.20.1</jackson.version>
5253
</properties>
5354

5455
<dependencies>
@@ -66,6 +67,16 @@
6667
<artifactId>picocli</artifactId>
6768
<version>${picocli.version}</version>
6869
</dependency>
70+
<dependency>
71+
<groupId>com.fasterxml.jackson.core</groupId>
72+
<artifactId>jackson-core</artifactId>
73+
<version>${jackson.version}</version>
74+
</dependency>
75+
<dependency>
76+
<groupId>com.fasterxml.jackson.core</groupId>
77+
<artifactId>jackson-databind</artifactId>
78+
<version>${jackson.version}</version>
79+
</dependency>
6980
<dependency>
7081
<groupId>ch.qos.logback</groupId>
7182
<artifactId>logback-classic</artifactId>
@@ -276,4 +287,4 @@
276287
<url>https://repo.maven.apache.org/maven2/</url>
277288
</repository>
278289
</repositories>
279-
</project>
290+
</project>

src/main/java/org/neo4j/dbcopy/DataReader.java

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/main/java/org/neo4j/dbcopy/DataTransfer.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.neo4j.dbcopy;
22

3+
import org.neo4j.dbcopy.io.DataReader;
4+
import org.neo4j.dbcopy.io.DataWriter;
35
import org.neo4j.driver.types.Node;
46
import org.neo4j.driver.types.Relationship;
57
import org.slf4j.Logger;
@@ -26,8 +28,6 @@ public DataTransfer(DataReader dataReader, DataWriter dataWriter, CopyOptions co
2628
}
2729

2830
Mono<Long> copyAllNodesAndRels() {
29-
var mappingContext = new MappingContext(10000);
30-
3131
var batchSize = copyOptions.batchSize();
3232
ProgressBar nodeProgressBar = new ProgressBar("Nodes", dataReader.getTotalNodeCount());
3333
ProgressBar relationshipProgressBar = new ProgressBar("Relationships", dataReader.getTotalRelationshipCount());
@@ -39,11 +39,10 @@ Mono<Long> copyAllNodesAndRels() {
3939
.buffer(batchSize)
4040
.doOnNext(batch -> nodeProgressBar.updateProgress(batch.size()))
4141
.flatMap(this::writeNodes, WRITER_CONCURRENCY)
42-
.doOnNext(mappingContext::add)
4342
.then(readRels()
4443
.buffer(batchSize)
4544
.doOnNext(batch -> relationshipProgressBar.updateProgress(batch.size()))
46-
.flatMap((List<Relationship> relationships) -> writeRels(relationships, mappingContext), 1)
45+
.flatMap(this::writeRels, 1)
4746
.reduce(0L, Long::sum)
4847
)
4948
.doOnSuccess(it -> LOG.info("Relationships writing complete - {} relationships written", it));
@@ -57,12 +56,12 @@ private Flux<Relationship> readRels() {
5756
return dataReader.readRelationships();
5857
}
5958

60-
private Flux<MappingContext.Mapping> writeNodes(List<Node> nodes) {
59+
private Mono<Void> writeNodes(List<Node> nodes) {
6160
return dataWriter.writeNodes(nodes, copyOptions);
6261
}
6362

64-
private Mono<Long> writeRels(List<Relationship> relationships, MappingContext mappingContext) {
65-
return dataWriter.writeRelationships(relationships, mappingContext, copyOptions);
63+
private Mono<Long> writeRels(List<Relationship> relationships) {
64+
return dataWriter.writeRelationships(relationships, copyOptions);
6665
}
6766

6867
}

src/main/java/org/neo4j/dbcopy/DataWriter.java

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)