Learn Julia (14): calling python modules
Tags: graphdb, julia, neo4j, python
Published: 2020-12-01 18:32:06

**Julia** is a very young language compared to **Python** or **Matlab**. Thus its ecosystem is not yet as large as that of **Python** or **Matlab**. It shall be a very exciting idea for Julia to be able to import existing Python modules and functions, isn't it? 

Today I am glad to have successfully fulfilled some graph database related work in **Julia** by importing some **Python** modules. So here I will present step by step what I have done just now.

## install pkg PyCall
```julia
using pkg
Pkg.add("PyCall")

```

## use PyCall with a correct Python env

I am using Anaconda for Python development. And there are three different Python versions on my machine which are managed by Conda envs. So I need to specify the correct Python path in julia ENV parameter and then re-build PyCall. 

```julia
ENV["PYTHON"] = "D:\\Anaconda3\\envs\\py36\\python.exe"
Pkg.build("PyCall")
using PyCall
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ap7r6ofw8b4dsddpkymb.PNG)

## import some modules

```julia
pyneo = pyimport("py2neo")
pyjson = pyimport("json")
```
## Data preparation

I faked a data file "data.json" with several french expressions. This file contains three french expression objects and each of them has "id","fr","zh" and "category" properties. The content of this file is as follows:
```json
[
	{
		"id": 1,
		"fr": "Tu me dégoutes!",
		"zh": "我讨厌你！ ",
		"category": "plainte"
	}, {
		"id": 2,
		"fr": "Je veux plus jamais te voir !",
		"zh": "我不愿再见到你！ ",
		"category": "plainte"
	}, {
		"id": 3,
		"fr": "T'es dingue !",
		"zh": "你疯了! ",
		"category": "plainte"
	}
]
```

```julia
datafile = open("./data.json", "r");
ss = read("data.json", String);
print(ss)
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/r8i6jhm8pul517rehj82.PNG)

Now try to parse the file content as a json object using imported **json** module.
```julia
d = pyjson.loads(ss)
println("d: $d")
```
It worked thus I can use **Pyhton**'s `json` module for parsing `json`-format string (I guess there shall still be issues when the  string format is not clean, to be tested in future).
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/oc6fdk3ccjxw4jr961mn.PNG)

## call Python neo4j database and test it
I use **Py2neo** module to connect to my local **Neo4j** database. And test it with a simple **Cypher** command. It works. However, I encounter an error while trying to create a `Node` in the `graph`. The type of a `Node` object has been converted into  `Dict` in **Julia**.
```julia
graph = pyneo.Graph("http://localhost:7474",username="neo4j",password="123456")

res = graph.run("match (n) return n limit 10")
print(collect(res))

n = pyneo.Node("testNode", name="test") 
println(typeof(n))

graph.create(n)  # create nodes in the graph db
```
Output:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qztkfmrbc9wdxz3tyktp.PNG)

## Create nodes using Cypher

Since the **Cypher** execution works properly, thus I have tried executing cmd `create (n:expression) set n.id=$id set n.fr=\"$fr\" set n.zh=\"$zh\" return n ` for each item of the dict generated from json file. It works and I can see the expressions in the Graph.

```julia
for i in d
    id = i["id"]
	fr = i["fr"]
	zh = i["zh"]
    res = graph.run("create (n:expression) set n.id=$id set n.fr=\"$fr\" set n.zh=\"$zh\" return n ")
    println(id, collect(res))
end
```
Console output:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/is4zkudfxzl2na2t4wak.PNG)

Neo4j snapshot:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wu31lm44skzogk167erz.PNG)