# System.mongodb calls fail despite having the connector installed and status Valid

**URL:** <https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903>\
**Category:** Ignition\
**Tags:** ignition81, vision\
**Created:** [August 16, 2023, 12:18am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903 "2023-08-16T00:18:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 12:18am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/1 "2023-08-16T00:18:17Z")

</div>

Using the snippet from [system.mongodb.listConnectorInfo - Ignition User Manual 8.1 - Ignition Documentation](https://docs.inductiveautomation.com/display/DOC81/system.mongodb.listConnectorInfo) yields an error (see below). The MongoDB connector is installed in the gateway and its status is "valid", and the scripting hint scope is set to "Gateway" and does properly hint mongo methods. Has anyone seen something like this before / know what to do? Freshly updated the gateway and designer to 8.1.31.

Valid connection:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/2/f22ab79e6ebffdbdb17ee826ae0c53c5a88b8547.png)

Context hint:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/7/07185de87d91284b7c5006f055edf3f1e208d2da.png)

Screencap of execution:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/c/b/cba5df38df94dc09c0674b3a90020fa9cacbc906.png)

Script code:

```auto
#Scripting / Project Library / Mongo
# Retrieve and print the returned list of connectors found.
def listconnectorinfo():
	
	connectors = system.mongodb.listConnectorInfo()
	 
	print connectors[0]['name']
	print connectors[0]['status']
	print connectors[0]['description']
	print connectors[0]['error']

```

Error text:

```auto
Mongodb.listconnectorinfo()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<module:Mongo>", line 4, in listconnectorinfo
AttributeError: 'com.inductiveautomation.ignition.designer.gui.tool' object has no attribute 'mongodb'

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 16, 2023, 12:26am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/2 "2023-08-16T00:26:22Z")

</div>

The script console is executing on your local machine. The mongodb functions are only available when _executing_ in the gateway. The 'script hint scope' drop-down in the script library affects the hints you get, but doesn't change how or where your function is actually executing.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 16, 2023, 12:34am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/3 "2023-08-16T00:34:21Z")

</div>

In case you are scratching you head over what to do next, I recommend placing the code you wish to test that requires gateway scope into a gateway message handler. You can use `system.util.sendMessage()` or `system.util.sendRequest()` in the script console, targeting that handler, to run your test code.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 12:49am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/4 "2023-08-16T00:49:22Z")

</div>

How did you know!

That's very helpful thank you. Is it possible to abstract the method so I can call a script by name? system.util.execute I think is not appropriate, and if I try to pass the method itself I get an error like

```auto
com.inductiveautomation.ignition.client.gateway_interface.GatewayException: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Error serializing parameters.

```

Is it possible to use some system utility for calling a script by name in this context?

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 12:55am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/5 "2023-08-16T00:55:01Z")

</div>

So if I want to use a Mongo database (example: for storing recipes), I need to connect a script to some kind of intermediate tag like a boolean "write\_mongo" which when flipped True would trigger a gateway tag change script? Or I would need to add a message script and send a system message that I want to write/read from the Mongo database?

I see that there are only Mongo bindings for Perspective, which sucks since I am using Vision, but if I can only execute these system.mongo functions in the Gateway that means they are off the table for directly invocation in a button-press, for instance?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 16, 2023, 12:59am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/6 "2023-08-16T00:59:19Z")

</div>

system.util.sendRequest, as Phil mentioned, is the way to go. You write one or more message handlers (which will be invoked on the gateway), and call them from the Vision client.

You can use getattr() on the `system.mongo` object to retrieve a callable function reference, but you probably don't need to do that.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 1:06am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/7 "2023-08-16T01:06:09Z")

</div>

I was thinking more like getattr on the Project Library object, if I am just trying to build a shortcut to calling project methods in the gateway, but this suffers the serialization issues for sending parameters.

I have a Library named "Mongo" which simply contains this listconnectorinfo() method -- what do I getattr(????, "listconnectorinfo") on? I can't send Mongo because of serialization, and I can't use str "Mongo".

I think I am asking: Is there a way to do something that looks like getattr(system.scripting.MyScripts, "myScript")

Something that is _almost_ (because this doesn't work):

```auto
# Payload looks like 
# {"library": "MyScripts", "script": "test_mongo_stuff", "args": [], "kwargs": {}}
def handleMessage(payload):
	return getattr(payload['library'], payload['script'])(
		*payload.get('args', []), 
		**payload.get('kwargs',{})
	)

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 16, 2023, 2:27am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/8 "2023-08-16T02:27:44Z")

</div>

You can use `locals()` to retrieve a callable reference to your project library by string name. Again, though, you probably don't need this. A sufficiently general system is basically just `eval()` with extra steps. Why not just have a handler for listConnnectionInfo, one for query, etc?

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 5:29am UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/9 "2023-08-16T05:29:14Z")

</div>

I'll give it a try with locals(), thanks for the pointer.

I tried eval() and it got upset, although I can't remember the exact error at the moment. eval() could be a possible solution, that would be fine.

I don't want to have to duplicate every script that might need to run through the gateway, if I can build a single bridging function that will effectively just run a project script in the gateway. Am I perhaps overlooking a builtin feature that would allow me to do this? I still do not have a very intuitive handle what runs on client vs Gateway nor Project vs Gateway.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 16, 2023, 12:11pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/10 "2023-08-16T12:11:50Z")

</div>

Just write your code to test in a project library:

```auto
def someTest(payload):
	#do something
	return someResult

```

Then have a gateway message handler to this:

```auto
	return someLibrary.someTest(payload)

```

Then in the script console, you can do this:

```auto
result = system.util.sendRequest('myProject', 'myTestHandler', {'someKey': 'someArg'})

```

Edit your script library test function to contain the code you wish to test. Then switch to the script console to run the short code part that calls it.

Presumably, the finished code will be run from gateway scope, because it must, and that gateway event can just call the same script library function.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 8:57pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/11 "2023-08-16T20:57:17Z")

</div>

@pturmel Yes this is what I have done, I just was hoping to be able to abstract it for two primary reasons: 1) I don't want to have to do this repeatedly if I can avoid it, and 2) the exercise helps me to understand better both the capabilities and general layout of the engine that I am working with.

@paul-griffith `locals()` is apparently empty in the context of handleMessage. `globals()` seems to be stuck waiting for the gateway forever, which I suppose isn't a surprise.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 16, 2023, 8:59pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/12 "2023-08-16T20:59:57Z")

</div>

Maybe `vars()` then. One of the builtins should expose project library scripts in a dictionary with simple string keys.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 16, 2023, 9:02pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/13 "2023-08-16T21:02:46Z")

</div>

> [@sherman](#):
>
> be able to abstract it for

Don't. It is a huge security hole. You don't want to allow passing arbitrary code or function names. Use a test project library script and test message handler. Delete what you no longer need before deploying to production.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 9:05pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/14 "2023-08-16T21:05:44Z")

</div>

Same response from `vars()` and `locals()`, which is only the things immediately available to the `handleMessage(payload)` method.

```auto
# what_local
def handleMessage(payload):
	return [("vars", vars()), ("locals", locals())]

```

```auto
system.util.sendRequest("test_project", "what_local", payload={"library": "MyScripts"})

```

```auto
>>>
[('vars', {'payload': {'library': 'MyScripts'}}), ('locals', {'payload': {'library': 'MyScripts'}})]
>>>

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 16, 2023, 9:09pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/15 "2023-08-16T21:09:06Z")

</div>

Don't access `vars()` or `locals()` or `globals()` in the message handler. There are legacy jython scope issues there. Access those in the function in the library script.

Gateway event handlers, in general, should be one-liners that simply pass all relevant event information to a project library script function that does the real work. The arrangement of my example was not accidental.

(I recommend this for all event handlers everywhere in Ignition, but most do not have the legacy scope problems. Still a best practice for code maintainance. This will remain true as long as events are monolithic project resources instead of per-event definition resources.)

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 9:10pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/16 "2023-08-16T21:10:29Z")

</div>

I am aware -- I am also comfortably far away from that security need being dominant over developmental hurdles. Everything is on a very closed system and I am the only developer at the moment. Also, the way that I am building our system has Ignition only as a piece of the puzzle -- it needs to interface with multiple systems for which it has no drivers.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 9:12pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/17 "2023-08-16T21:12:19Z")

</div>

> Don't access `vars()` or `locals()` or `globals()` in the message handler. There are legacy jython scope issues there. Access those in the function in the library script.

If am not accessing them there, there is no point.

> Gateway event handlers, in general, should be one-liners that simply pass all relevant event information to a project library script function that does the real work. The arrangement of my example was not accidental.

Unfortunate, but I am seeing that this is the only way forward. I guess I just need the extra decorator for every method like this.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 16, 2023, 9:13pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/18 "2023-08-16T21:13:45Z")

</div>

> [@sherman](#):
>
> If am not accessing them there, there is no point.

This makes no sense. Why is there no point?

> [@sherman](#):
>
> I guess I just need the extra decorator for every method like this.

Why do you need a decorator?

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [August 16, 2023, 9:24pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/19 "2023-08-16T21:24:12Z")

</div>

> This makes no sense. Why is there no point?

If I can't access the method object that I need in the place where I need to invoke it, I have no further use for it here.

> Why do you need a decorator?

Sorry, I shouldn't use this term here, it has a specific meaning and that is confusing. I mean I need to make a one-liner for each of the project methods I want to invoke in the Gateway scope, as you suggested. Effectively decorating them, although not literally.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 16, 2023, 9:37pm UTC](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903/20 "2023-08-16T21:37:11Z")

</div>

In your event handler, you could do something like this:

```auto
return getattr(someLibraryScript, payload.pop('functionNameKey'))(payload)

```

That will call any function in `someLibraryScript` whose name you supply in the payload, and pass that function the rest of the payload.

It will not call anything outside of `someLibraryScript`, so it is relatively safe if you dedicate `someLibraryScript` to functions expecting remote calls.

[Next page](https://forum.inductiveautomation.com/t/system-mongodb-calls-fail-despite-having-the-connector-installed-and-status-valid/77903.md?page=2)
