Amazon Neptune: How to create custom vertex id in Python using tinkerpop/gremlinpython package? - python-3.x

As outlined here https://docs.aws.amazon.com/neptune/latest/userguide/access-graph-gremlin-differences.html custom vertex ids can only be set with the unquoted id property, i.e., g.addV('label1').property(id, 'customid'). How can one accomplish this using the gremlinpython package? I see an id function in gremlin_python.process.graph_traversal, but I get an UnsupportedOperationException (as expected) when attempting to use that.

You should just have to import T which is the class that hold the id and label members:
from gremlin_python.process.traversal import T
then use it as:
g.addV('label1').property(T.id, 'customid').iterate()
You can of course choose to import id from T so as to make the syntax synonymous with the example Gremlin in your question such that you may omit the T - some folks prefer that style.
It may be worth looking at the reference documentation for other common imports that Gremlin uses.

Related

How do you extend a library created variable in onvif python?

onvif python will create base variables from WSDL but not the optional elements. How do I add the optional variables to the existing definition?
as in a = create(sometype)
This defines the elements a.b and a.c.
I need to add elements a.c.d, a.c.e.g and a.c.e.h.
The short answer: It depends on what the existing variable is.
The longer answer: Since the existing variable is defined by a third party library with little to no visibility, run the code under a debugger that will tell you what the existing variable is, e.g, list, dict, etc. From that information look in the python documentation if you are not familiar with that type of variable.

Using related models with conditional expression

Goal: use a related model attribute as a filter inside a conditional expression for an annotation.
I'm currently adding some functionality to an old Django app, this app has some design issues and i have nothing to do with it. After some research I found conditional expressions, this is great and what I needed.
However I'm not being able to make it.
Let's have model A, model B and model C.
class ModelA(models.Model):
name=models.Charfield()
reference=models.ForeignKey('app.ModelB')
class ModelB(models.Model):
name=models.Charfield()
class ModelC(models.Model):
name=models.Charfield()
reference=models.ForeignKey('app.ModelB', related_name='some_reference')
bool_field=models.BooleanField()
And this is what I would like to do:
ModelA.objects.all().annotate(some_field=When(Q(reference__some_reference__bool_field=True),
then=F('reference_some_reference_name')))
This should work since it is being interpreted by python, but I get some Syntax Error from MySQL.
What am i doing wrong? Is this even possible?
This is what I'm getting:
django.db.utils.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHEN `ParametrosPreciosProveedor`.`already_iva` = 1 THEN `ParametrosPreciosProve' at line 1")
'ParametrosPreciosProveedor' is ModelC in this example and 'already_iva' is bool_field.
I would try removing the When and then parts of the annotation. Q objects do those automatically - you don't define those terms in Python.
ModelA.objects.all().annotate(some_field=Q(reference__some_reference__bool_field=True),
F('reference_some_reference_name')))
Check out the docs to see how to use Q()

how do i prevent redundant package and class names in python

I have a complex class hierarchy which involves harnessing a wide array of OS commands to provide a uniform API to them in an automation library. Some of these commands are accessed via a cli interface, others via a rest based interface, and the classes therein have package names such as these:
cmd.interface.cli.mgmt
cmd.interface.cli.support
cmd.interface.rest
cmd.driver.cli.network_config
cmd.result.cli.network_config
cmd.driver.cli.stats
cmd.result.cli.stats
cmd.driver.rest.network_interface
cmd.result.rest.network_interface
etc, etc.
there are many of these, and they are all grouped logically and have a hierarchy of base classes, and they all contain a single class definition of basically the same name as the last file name in the package path.
i.e., an import statement and then "constructor" usage would look like this:
import cmd.driver.cli.network_config
.
.
.
config_driver = cmd.driver.cli.network_config.NetworkConfig(...)
I find the redundancy in this sort of class access to be really annoying, and it makes the code look kind of stupid.
Is there a good way to remove this naming redundancy while keeping the modules separate and intact?
Here are a few things I do not want to do to address this issue:
1.
from cmd.driver.cli.network_config import NetworkConfig as CliDriverNetworkConfig
from cmd.result.cli.network_config import NetworkConfig as CliResultNetworkConfig
from cmd.driver.rest.network_config import NetworkConfig as RestDriverNetworkConfig
(ugh!)
I don't want to pretend there is a cute name possible for each of these things. I really want to expose all the relevant information at time of use:
config_driver = cmd.driver.cli.network_config.NetworkConfig(...)
(but I really want, and this should be enough to make the code understandable:
config_driver = cmd.driver.cli.NetworkConfig(...)
)
put 30 or so of such class defs in cmd/driver/cli/__ init __.py
(also yucky)
in perl, this would be done in this manner:
use Cmd::Driver::CLI::Network_Config;
.
.
.
my $config_driver = Cmd::Driver::CLI::Network_Config->new(...);
is there any mechanism in python that would allow me to more succinctly call the constructor on these classes without the package name redundancy and without hiding important details of which class out of several with similar but reliably distinct full names is being called?
................................................
ADDITIONAL COMMENT at post + 1 hour:
It occurs to me that perl is also doing the same sort of thing, where the package is Cmd::Driver::CLI::Network_Config and the class method being called therein is 'new'. Thus the prettier look of the call in this case.
I guess if I name the module cmd.driver.cli.NetworkConfig and put a package scope method called 'new' which just calls cmd.driver.cli.NetworkConfig.NetworkConfig(...) I would get the same effect, such that I could then make the call:
import cmd.driver.cli.NetworkConfig
.
.
.
config_driver = cmd.driver.cli.NetworkConfig.new(...)
hmmmm... i realize that this may not be "pythonic" in several senses, and I don't like mucking about behind the scenes too much (this sort of thing is always a risk), but maybe this is the way to get what i want if i'm dead-set on it...
................................................
ADDITIONAL COMMENT at post + 1 week:
Gosh no up-votes even? Kind of a serious question. Perhaps I should not have said how I'd do this in perl... :-p Ah, well.
My proposition : uses __ import__ to define your function for instance.
def myInit(pathImport, *args):
t = __import__(pathImport+".network_config", globals(), locals(), [], 0)
return t.NetworkConfig(*args)
and use is
config_driver = myInit('cmd.driver.cli', ...)
Try something like this in your top level module or __init__.py:
# import submodules, exposing them to things that import this module directly
from cmd.interface.cli import mgmt
from cmd.interface.cli import support
from cmd.interface import rest
from cmd.driver.cli import stats as driver_stats
from cmd.result.cli import stats as result_stats
# hide unneeded variables from things that import this module (optional)
__all__ = ['mgmt', 'support', 'rest', 'driver_stats', 'result_stats']
This will expose the simplified names as module member variables to anything that references your root module. You can even do variations of this pattern at multiple levels of your hierarchy.

Python, bulbs, resxter . Getting bool scalar returned by gremlin script from bulbs

I am writing python scripts to extract data from multiple sources and put it in a graph in a certain structure.
I am using bulbs models for all the data. I have models for all relevant node types and relationships. My edge models have not additional properties except 'label'.
As it is in development, I run the same script multiple times. I use get_or_create to prevent duplicate nodes but edges do not have that method. I do not have the object for existing edge since it was created in a previous run of the script.
I saw several question talking about similar things with answers from espeed like this, but I could not find a satisfactory answer for my specific issue.
What would be the simplest code for this method?
Presently I am trying to do this via loading a gremlin script; as suggested by Stephen; with following function:
def is_connected(parent, child, edge_label) {
return g.v(parent).out(edge_label).retain([g.v(child)]).hasNext()
}
And the the following python code.
g.scripts.update('gremlin_scripts/gremlin.groovy')
script = g.scripts.get('gremlin:is_connected')
params = dict(parent=parent_node.eid, child=menu_item_v.eid, edge_label='has_sub_menu_item')
response = g.gremlin.execute(script, params)
I can't quite figure out how to get the bool result into python. I've also tried the g.gremlin.query(script, param)
Here's one way to do it:
parent_v.out(rel_label).retain(child_v).hasNext()
So, from the parent, traverse out to all children (i assume that "out" is the direction of your relationship - how you choose to implement that is specific to your domain) and determine if that child is present at any point via retain.

PHPStorm: 'Go to declaration' on class names in string literals

I'm using PHPStorm EAP version PS-138.940.
I have code as follows:
Config(__NAMESPACE__."\ObjectsToIdentifiers")->oldTables = array('Modules\Old\Model\DeviceStock','Modules\Old\Model\ProductPack','Modules\Old\Model\SpareStock','Modules\Old\Model\ConsumStock');
The functionality is irrelevant in this case. Important are the entries in the array. These are fully qualified class names - the leading / is omitted, but adding it doesn't solve my problem. I want to be able to click inside one of the string literals, press Ctrl+B and be redirected to the class definition.
Note that this works in ExtJS (javascript framework) where a string literal like
"MyApp.namespace.view.MyComponent"
will take me there.
Is there any way to manually configure this or do I have to submit a feature request. If so, how can I do that?
Update 1:
I created a feature request on JetBrains Youtrack: http://youtrack.jetbrains.com/issue/WI-24262
Came across this question looking for something in Storm that would let me quickly convert "\Some\ClassName" to Some\ClassName::class like an Intention or plugin, but so far have found nothing.
i'm surprised the ::class static property hasn't been mentioned. It produces the FQN of the Class, and resolves from import aliases.
The following should be a legit rewrite that the IDE can resolve:
// Same __NAMESPACE__, so no prefix needed
Config(ObjectsToIdentifiers::class)
->oldTables = [
Modules\Old\Model\DeviceStock::class,
Modules\Old\Model\ProductPack::class,
Modules\Old\Model\SpareStock::class,
Modules\Old\Model\ConsumStock::class
];
// or, if you import the classes:
use Modules\Old\Model\DeviceStock as OldDeviceStock;
// you can refer to
OldDeviceStock::class;
Unfortunately, right now if you jump-to-definition of the alias, Storm won't take you to the actual class, but where the alias is defined. Not terribly helpful, but gets you halfway since the actual class is right there.

Resources