2.7 KiB
Create migrations
Let's create nodes called Users:
migrate create -ext cypher -dir db/migrations -seq create_user_nodes
If there were no errors, we should have two files available under db/migrations folder:
- 000001_create_user_nodes.down.cypher
- 000001_create_user_nodes.up.cypher
Note the cypher extension that we provided.
In the .up.cypher file let's create the table:
CREATE (u1:User {name: "Peter"})
CREATE (u2:User {name: "Paul"})
CREATE (u3:User {name: "Mary"})
And in the .down.sql let's delete it:
MATCH (u:User) WHERE u.name IN ["Peter", "Paul", "Mary"] DELETE u
Ideally your migrations should be idempotent. You can read more about idempotency in getting started
Run migrations
migrate -database ${NEO4J_URL} -path db/migrations up
Let's check if the table was created properly by running bin/cypher-shell -u neo4j -p password, then neo4j> MATCH (u:User)
The output you are supposed to see:
+-----------------------------------------------------------------+
| u |
+-----------------------------------------------------------------+
| (:User {name: "Peter") |
| (:User {name: "Paul") |
| (:User {name: "Mary") |
+-----------------------------------------------------------------+
Great! Now let's check if running reverse migration also works:
migrate -database ${NEO4J_URL} -path db/migrations down
Make sure to check if your database changed as expected in this case as well.
Database transactions
To show database transactions usage, let's create another set of migrations by running:
migrate create -ext cypher -dir db/migrations -seq add_mood_to_users
Again, it should create for us two migrations files:
- 000002_add_mood_to_users.down.cypher
- 000002_add_mood_to_users.up.cypher
In Neo4j, when we want our queries to be done in a transaction, we need to wrap it with :BEGIN and :COMMIT commands.
Migration up:
:BEGIN
MATCH (u:User)
SET u.mood = "Cheery"
:COMMIT
Migration down:
:BEGIN
MATCH (u:User)
SET u.mood = null
:COMMIT
Optional: Run migrations within your Go app
Here is a very simple app running migrations for the above configuration:
import (
"log"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/neo4j"
_ "github.com/golang-migrate/migrate/v4/source/file"
)
func main() {
m, err := migrate.New(
"file://db/migrations",
"neo4j://neo4j:password@localhost:7687/")
if err != nil {
log.Fatal(err)
}
if err := m.Up(); err != nil {
log.Fatal(err)
}
}