2

I see a strange behavior with the neo4j-bolt-driver. When I use Pycharm to run my code it works perfectly well and for a single query to neo4j I get the below response:

type: neo4j.node    # I pulled out the type of the element.
<Node id=3820 labels={'city'} properties={'ID': 'xddy', 'name': 'california'}>

Now when I package my code and create an .egg out of it, and then use the terminal to run the script for the same input to the same database I get the below response:

type: neo4j.node    # I pulled out the type of the element.
(_3820:city {ID: 'xddy', name: 'california'})

Now have a look at the difference in the responses, the type is the same just the keys to the object are missing.

And this leads to an AttributeError. Worse is I have to manually parse the data into a dict so that I can process it.


Side Effects:

try:
    props = node[admin].properties
    node_chain[list(node[admin].labels)[0]] = props
    address.append(props['name'])
except AttributeError:

    # try to convert (_3820:city {ID: 'xddy', name: 'california'})
    # to {'ID': 'xddy', 'name': 'california'}
    # and add it to an existing dict with the key `city`

    string_rep = str(node[admin])
    splitted = string_rep.split('{')
    label = splitted[0].split(':')[-1].strip()
    payload_string = "{ " + splitted[1][:-1]
    clean = payload_string.replace("'", " ").replace(":", "':'").replace(",", "','")\
        .replace("{", "{'").replace("}", "'}")
    temp_dict = ast.literal_eval(clean)
    payload_dict = {k.strip(): v.strip() for k, v in temp_dict.items()}
    address.append(payload_dict['name'])
    node_chain[label] = payload_dict

I am looking for two answers:

  • Is there an issue in the bolt driver or is it just my code when run from an egg
  • Is there a better way to parse the invalid content into a dict?
Rebecca Nelson
  • 1,286
  • 2
  • 9
  • 20
iam.Carrot
  • 4,976
  • 2
  • 24
  • 71
  • Are you running in the same environment between PyCharm and your shell? I would suspect what has happened here is that they are not the same environment and that each one has a different version of the `neo4j-driver` module. Are you using a virtual environment for this? In PyCharm, under Preferences -> Project -> Project Interpreter, is the interpreter set to the same executable path as `whereis python` (or `python2` or `python3` if that is what you use) returns when executed in your shell? Or, if you use a virtualenv, is the PyCharm project interpreter set to that? – Rebecca Nelson Apr 14 '18 at 11:04
  • @RebeccaNelson They both are using the same virtual env. Wait have they changed the response from the `Bolt` query in a few versions? if so, which one is the latest (hopefully the one with proper labels and properties)? – iam.Carrot Apr 14 '18 at 11:06
  • Well... well I'm stumped. They should be the same version then... Okay, I realize I'm asking you to "prove" what you're saying, and I apologize, but for completeness' sake, what is the path that the project interpreter is set to, and what is the exact command(s) you use to activate the virtualenv and execute from shell? – Rebecca Nelson Apr 14 '18 at 11:09
  • @RebeccaNelson in `Pycharm` the interpreter path is `X:\Projects\Python\HybridCart\venv\Scripts\Python` while on the terminal when I run it I `cd X:\Projects\Python\HybridCart\venv\Scripts\` and then type in `activate` and then type in `python` to start the `console` and then just do a import statement followed by a `process_order()` function call. – iam.Carrot Apr 14 '18 at 11:13
  • The API for `neo4j-driver` has indeed changed very recently. I actually had a new deploy of a project in which `neo4j-driver` was not pinned to a specific version, and it completely broke my app when updating the module; even between two minor version numbers if I recall. For reference, this was about 2 weeks ago, and I had originally set the version about 2 months ago. – Rebecca Nelson Apr 14 '18 at 11:13
  • @RebeccaNelson can you please point out, out of the two response structures I have shown in the question, which one is the latest one? – iam.Carrot Apr 14 '18 at 11:15
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/168979/discussion-between-rebecca-nelson-and-iam-carrot). – Rebecca Nelson Apr 14 '18 at 11:16

1 Answers1

1

You have a discrepancy in your execution environments.

Even though you are using the same virtual environment for both shell execution and the PyCharm project interpreter, when executing an .egg the execution environment may be modified to pull in fresh copies of all the libraries, which are not necessarily installed to the "global" module path ("global" here meaning either system-wide when not using a virtualenv, or in the python modules of the virtualenv).

Your PyCharm notes that it is using version 1.5.3 of the neo4j-driver module, but the version that pip pulled in to your .egg executation environment is 1.6.0a, the latest at the time of dependency resolution. And so, when executing it from the shell, you are using a different version of neo4j-driver.

That in and of itself wouldn't be so bad, but...

There are currently breaking changes between 1.5.3 and 1.6.0 of neo4j-driver.

1.6.0 changed the paths of some of the modules, so specific imports might break. It seems it also changed the format of some of its data objects, as you've seen in your example.

At first it would seem that this is just a consequence of using an unstable tag of the version, but it's very possible that these changes might be here to stay, as it is a new version.

To ensure the same version is installed by pip/setuptools, pin the version number.

1.6.0 drastically changed the API in some respects. Since you were developing against 1.5.3, you will have to either change your API to handle both versions (and possibly risk it breaking again when future updates are released), or pin it to a particular version.

To pin it, wipe out any existing versions of neo4j-driver by removing all binaries from your build dir, uninstall it with pip, then update your setup.py or other dependency management tool to point to the specific version you are developing with.

For setup.py, add ==1.5.3 to the end of the name of the library in the install_requires, tests_require or other relevant sections.

Rebecca Nelson
  • 1,286
  • 2
  • 9
  • 20