gremlinpython - return id and label as string
Asked Answered
I

3

4

I'm using gremlinpython 3.4.1 on Python 3.7.2, and when get vertex/edge responses it is providing <T.id: > for id and <T.label: 3> for the label. How would I get it to provide the string value for id and label in the response instead? My aim is take the output and generate JSON

The output:

python3 stackoverflow.py
[{'name': ['USA'], 'parentname': ['USA'], 'shortname': ['US'], <T.id: 1>: 'country-us', 'parentid': ['country-us'], <T.label: 3>: 'Country'}]

The code:

from gremlin_python import statics
from gremlin_python.process.anonymous_traversal import traversal
from gremlin_python.process.graph_traversal import __
from gremlin_python.process.strategies import *
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.traversal import T
from gremlin_python.process.traversal import Order
from gremlin_python.process.traversal import Cardinality
from gremlin_python.process.traversal import Column
from gremlin_python.process.traversal import Direction
from gremlin_python.process.traversal import Operator
from gremlin_python.process.traversal import P
from gremlin_python.process.traversal import Pop
from gremlin_python.process.traversal import Scope
from gremlin_python.process.traversal import Barrier
from gremlin_python.process.traversal import Bindings
from gremlin_python.process.traversal import WithOptions

CLUSTER_ENDPOINT = "removed"
PORT = "8182"
g = traversal().withRemote(DriverRemoteConnection('wss://' + CLUSTER_ENDPOINT + ':' + PORT + '/gremlin','g'))

response = g.V().has('name', 'USA').limit(1000).hasLabel('Country').valueMap(True).toList()
print(response)

BTW - I have attemped to use .with_(WithOptions.ids) for example:

response = g.V().has('name', 'USA').limit(1000).hasLabel('Country').valueMap(True).with_(WithOptions.ids).toList()

for which I get the following error:

gremlin_python.driver.protocol.GremlinServerError: 599: {"requestId":"bf74df44-f064-4411-a1cb-78b30f9d2cf6","code":"InternalFailureException","detailedMessage":"Could not locate method: NeptuneGraphTraversal.with([1])"}

Incorporeal answered 3/5, 2019 at 4:31 Comment(0)
F
4

Additionally, to the project() example that was already given, you could do something like the following if you can't or don't want to specify the property names:

g.V().has('name', 'USA').limit(1000).hasLabel('Country').
  map(union(project('id','label').
              by(id).
              by(label),
            valueMap()).unfold().
      group().
        by(keys).
        by(select(values))) // select(values).unfold() if you only have single values
Filmore answered 3/5, 2019 at 15:0 Comment(3)
Thank you. I get the error: NameError: name 'union' is not definedIncorporeal
Have you tried __.union? I'm not sure how to make static imports in Python.Filmore
I like the approach as it doesn't require me to list out the values I want to include in the responseIncorporeal
G
1

You could try to project the results.

g.V().has('name', 'USA').limit(1000).hasLabel('Country') \
    .project('id', 'label', 'name', 'parentname', 'shortname', 'parentid') \
    .by(id) \
    .by(label) \
    .by('name') \
    .by('parentname') \
    .by('shortname') \
    .by('parentid') \
    .toList()
Gluconeogenesis answered 3/5, 2019 at 8:12 Comment(1)
Thank you. This works with a minor modification where id is T.id and label is T.label: g.V().has('name', 'USA').limit(1000).hasLabel('Country') \ .project('id', 'label', 'name', 'parentname', 'shortname', 'parentid') \ .by(T.id) \ .by(T.label) \ .by('name') \ .by('parentname') \ .by('shortname') \ .by('parentid') \ .toList()Incorporeal
D
0

You could replace your EnumMeta dict keys with the actual values. You would need to add an unfold() after your valueMap to use this function.

from gremlin_python.process.traversal import T

def get_query_result_without_enum_metas(query_result):
    return [replace_enum_metas(d) for d in query_result]

def replace_enum_metas(dict):
      dict_key = (*dict,)[0]
      if type(dict_key) is str:
        return dict
      elif type(dict_key) is T:
        return {dict_key.name: dict[dict_key]}

input: [{'vertex_property': ['Summary']}, {<T.id: 1>: '4b30f448ee2527204a050596b'}, {<T.label: 3>: 'VertexLabel'}]

output: [{'vertex_property': ['Summary']}, {'id': '4b30f448ee2527204a050596b'}, {'label': 'VertexLabel'}]
Dita answered 3/5, 2019 at 20:14 Comment(2)
I like this approach as it doesn't require me to list out the values I want to include in the response... however I'm not clear on the 'self' argument on the get_query_result_without_enum_metas function - could you perhaps update your answer to include how and where that function is being used?Incorporeal
The self is totally not needed. I had them there only because these methods were members of a larger class I had created. I updated the answer.Dita

© 2022 - 2024 — McMap. All rights reserved.