Copying contents of Database A -> B

Hi Everyone,

I started messing around with some multi-tenancy application with Neo4J as the backend. So to keep data seperate i want each tenant to use a single database. But to deploy a tenant i need to create some base nodes for some details.

Is there an easy way using cypher to copy all nodes/relations in a database (template) to a freshly created database? I took a look at fabric but it's more oriented at querying multiple databases for reading. It can be a simple solution as it's probably just under 100 nodes/relationships. I don't want to use the commandline tools as i want to execute it from my application using the Python driver.

Edit:
Running Neo4j 4.1.0 Enterprise edition from Neo4j Desktop

Hi Kevin.

You can try https://neo4j.com/docs/labs/apoc/current/export/cypher/
It is very powerful. Only problem is that the subgraph that you want to replicate should not be very big, however in your case 100 node/rel it is good to go

I've also been looking at this. It's looking promising. We're just using the database to allow us to more dynamically seed the others. So this will never be a huge amount of data.

If it is like training program that you like to provide your participants to start with. Then better you try to develop small DB with basic node and relationships and start from there.

I've made some progress in terms of the issue. Unfortunately i'm still running into a brick wall. I'm now running the export like:

CALL apoc.export.cypher.all(null, {format: \"plain\",useOptimizations: {type: \"UNWIND_BATCH\", unwindBatchSize: 20}}) YIELD cypherStatements RETURN cypherStatements

Output:

"CREATE CONSTRAINT ON (node:`UNIQUE IMPORT LABEL`) ASSERT (node.`UNIQUE IMPORT ID`) IS UNIQUE; UNWIND [{_id:0, properties:{name:"Administrator"}}] AS row CREATE (n:`UNIQUE IMPORT LABEL`{`UNIQUE IMPORT ID`: row._id}) SET n += row.properties SET n:Role; UNWIND [{_id:1, properties:{name:"ALL_ACCESS"}}] AS row CREATE (n:`UNIQUE IMPORT LABEL`{`UNIQUE IMPORT ID`: row._id}) SET n += row.properties SET n:Permission; UNWIND [{start: {_id:0}, end: {_id:1}, properties:{}}] AS row MATCH (start:`UNIQUE IMPORT LABEL`{`UNIQUE IMPORT ID`: row.start._id}) MATCH (end:`UNIQUE IMPORT LABEL`{`UNIQUE IMPORT ID`: row.end._id}) CREATE (start)-[r:HAS_PERMISSION]->(end) SET r += row.properties; MATCH (n:`UNIQUE IMPORT LABEL`) WITH n LIMIT 20000 REMOVE n:`UNIQUE IMPORT LABEL` REMOVE n.`UNIQUE IMPORT ID`; DROP CONSTRAINT ON (node:`UNIQUE IMPORT LABEL`) ASSERT (node.`UNIQUE IMPORT ID`) IS UNIQUE; "

But there is a problem. When I input the output of this query into my python session.run as query parameter i get the issue that is only allowed to run a single query. I'm running this test with just 2 nodes and a single relation to keep it easy.

neo4j.exceptions.CypherSyntaxError: {code: Neo.ClientError.Statement.SyntaxError} {message: Expected exactly one statement per query but got: 6 (line 0, column 0 (offset: 0))
"CREATE CONSTRAINT ON (node:`UNIQUE IMPORT LABEL`) ASSERT (node.`UNIQUE IMPORT ID`) IS UNIQUE;"

Is it possible to export them as multiple records or another way to achieve the goal?

image

I've split the returned cypher string on ";\n" and it works great. There is ofcourse the catch that this needs more application headroom. So i would still like to explore the other possibilities to minimise this.