能否在Python中从字节码生成Gremlin查询?

7

能否从字节码生成gremlin脚本?

我正在进行一个POC,需要通过Gremlin API查询图形Azure CosmosDB数据库。

目前,Azure CosmosDB不支持字节码。Azure开发团队已经开始研究此问题,但尚未发布发布时间表。

我想准备工作代码,以便在将来字节码支持普遍可用时需要最少的重构。

根据Apache TinkerPop文档,有两种提交Gremlin查询的方法:字节码和脚本。

# script
client = Client('ws://localhost:8182/gremlin', 'g')
list = client.submit("g.V().has('person','name',name).out('knows')",{'name': 'marko'}).all()

# bytecode
g = traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
list = g.V().has("person","name","marko").out("knows").toList()

“字节码方式”对我来说更有效率(语法检查、IDE智能提示等),此外我对创建DSL(特定领域语言)很感兴趣。
是否可能使用流畅的API并将其序列化为字符串,类似于这样的方式:
client = Client('ws://localhost:8182/gremlin', 'g')
g = traversal()
q = g.V().has("person","name","marko").out("knows").toString()
list = client.submit(q).all()

我正在使用Python 3.5和GremlinPython 3.4.0


1
此外,还有gremlinpy,它可以为您构建带有绑定参数的脚本。个人认为(由于供应商缺乏字节码支持的状态,例如CosmosDB),如果您想使用Python,则这可能是更好的方法。 - Sascha
@Sascha 谢谢,我一定会尝试的。我可能错了,但我认为编写翻译器会更有益,因为它使我能够使用GraphTraversal扩展编写DSL,并将字节码输出转换为Groovy脚本。在某个时候,当字节码可用时,我将切换到字节码。不确定这是否也适用于gremlinpy。 - Sebastian Widz
1个回答

2

“从字节码生成遍历的字符串表示”是完全可能的。TinkerPop已经为Groovy和Python脚本做到了这一点(主要是为了测试,但还有其他用途,比如支持字节码中的lambda表达式以及其他实用功能)。我们通过ScriptTranslator实现来完成这一操作,其中Groovy有一个实现,而Python有两个实现(其中一个实现实际上是针对Jython的)。当然问题在于,所有这些ScriptTranslator实例都是针对JVM的,听起来你需要的是针对原生Python的东西。”
也许你可以检查一下 PythonTranslator 的代码,并在本地 Python 中实现它?基本上,这只是一堆 if-then 和字符串拼接。

感谢您指引我使用PythonTranslator。我还发现有一个类似的JavaScript请求 https://issues.apache.org/jira/browse/TINKERPOP-1959 和 https://github.com/apache/tinkerpop/pull/952,我还没有验证过,但也许 https://github.com/apache/tinkerpop/blob/master/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js 更容易移植到Python? - Sebastian Widz
也许 - 那样做。无论哪种方式更容易阅读。主要是解析字节码并从中构建Gremlin字符串。正如你可以从所有现有的示例中看到的那样,这并不是非常困难。只是需要一些工作。 - stephen mallette
我终于找到时间来移植PythonTranslator.java。它几乎完成了,但是需要一些指导。我在python中找不到TraversalStrategyProxy和ConnectiveP类。在gremlin_python中跳过它们是否安全? - Sebastian Widz
还需要建议,是否值得为翻译后的脚本创建绑定?我在某处(可能是tinkerpop的文档)阅读到,使用参数化查询有助于提高性能。如果是这样,哪些部分应该和不应该被参数化,例如所有参数包括属性和标签名称应该被更改为参数,还是只有值例如在.has() 步骤中? - Sebastian Widz
你可以在Python中跳过ConnectiveP类,但你可能仍然需要考虑它 - 该类基本上处理P.and / P.or。同样,你应该考虑TraversalStrategyProxy代表什么 - 基本上只是对g.withStrategy()的调用(我认为这不会更复杂)。尽管动态参数化可能会带来改进,但我不会尝试这样做。据我所知,Groovy或JS翻译器都不会尝试这样做。 - stephen mallette

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接