snapshot of https://github.com/golang-migrate/migrate.git (master, 2026-09-15; blobs > 131072B omitted)
This commit is contained in:
97
database/neo4j/TUTORIAL.md
Normal file
97
database/neo4j/TUTORIAL.md
Normal file
@@ -0,0 +1,97 @@
|
||||
## 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](GETTING_STARTED.md#create-migrations)
|
||||
|
||||
## 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)
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user