I am using Bulbflow to access Neo4j through python.
I'm now trying to save a python list as a node property, but am consistently running into errors. From the documentation, I can see that lists are an accepted type when defined in models, but I'd like to save a list property after the models are defined, i.e.
anode = g.vertices.get(123)
anode.specs = [(2, 0.27911702036756064), (5, 0.6708785014712791)]
anode.save()
But I get the following error:
SystemError: (
{'status': '200',
'content-length': '142',
'content-type': 'application/json; charset=UTF-8',
'access-control-allow-origin': '*',
'server': 'Jetty(6.1.25)'},
'"java.lang.IllegalArgumentException:
Unknown property type on: [[2, 0.27911702036756064], [5, 0.6708785014712791]],
class java.util.ArrayList"')
I tried using the convert_to_db
function, but wasn't sure what the syntax was.
Any ideas on how to achieve this? Is the problem that I have a list of tuples?
Thanks!
============== UPDATE ==============
Following Peter's suggestion, I tried the same with a simple flat list and ran into the same error:
SystemError: (
{'status': '200',
'content-length': '172',
'content-type': 'application/json; charset=UTF-8',
'access-control-allow-origin': '*',
'server': 'Jetty(6.1.25)'},
'"java.lang.IllegalArgumentException:
Unknown property type on: [0.0, 0.0, 0.0, 0.42659109777029425, 0.0, 0.0, 0.0, 0.0, 0.5234052770685714, 0.0],
class java.util.ArrayList"')
Any ideas?
Neo4j only supports lists that contain primitive types such as string
, int
, bool
, etc (mixed types in a list aren't allowed).
Here are the property types Neo4j supports:
http://docs.neo4j.org/chunked/preview/graphdb-neo4j-properties.html
To store a mixed-type list
in Neo4j, you can save it as a JSON document string.
Bulbs has a Document
Property
type that does the dict
<->json
conversion for you.
See...
If you working with a generic Vertex
or Edge
, you need to do this conversion manually before you save it:
specs = [(2, 0.27911702036756064), (5, 0.6708785014712791)]
anode = g.vertices.get(123)
anode.specs = g.client.type_system.database.to_document(specs)
anode.save()
However, if you are using a Model
, Bulbs will do the conversion for you. Simply define your model using the Document
property instead of List
:
# people.py
from bulbs.model import Node, Relationship
from bulbs.property import String, DateTime, Document
from bulbs.utils import current_datetime
class Person(Node):
element_type = "person"
name = String(nullable=False)
specs = Document()
class Knows(Relationship):
label = "knows"
timestamp = DateTime(default=current_datetime, nullable=False)
...you can then use your model like this...
>>> from people import Person, Knows
>>> from bulbs.neo4jserver import Graph
>>> g = Graph()
>>> g.add_proxy("people", Person)
>>> g.add_proxy("knows", Knows)
>>> specs = [(2, 0.27911702036756064), (5, 0.6708785014712791)]
# You can save specs when you create it...
>>> james = g.people.create(name="James", specs=specs)
# ...or save it after creation...
>>> julie = g.people.create(name="Julie")
>>> julie.specs = specs
>>> julie.save()