th.nim
import nimpy
import nimongo.bson
import nimongo.mongo
proc fib(): seq[Bson] {.exportpy.} =
var m: Mongo = newMongo()
let connected = m.connect()
let col = m["feed"]["post"]
var docs: seq[Bson]
for document in col.find(%*{}).items():
docs.add(document)
return docs
main.py
import nimporter
import th
h = th.fib()
for item in h:
print(item)
and in nimporter
module at line 123 i added two compile parameters
'-d:nimOldCaseObjects', #because of an error
'--bound_checks:off', #because of an error
Output:
<capsule object NULL at 0x7f1975a47ae0>
<capsule object NULL at 0x7f1975a77d50>
<capsule object NULL at 0x7f1975a77f60>
<capsule object NULL at 0x7f19759488a0>
<capsule object NULL at 0x7f1975948840>
...
how can i get a data structure like dict or json in python?
PyCapsules
are defined here . You are receiving Bson
ref objects in a capsule at your python code, and if I'm understanding it correctly, they are C pointers. You could modify your code to return strings, or any other type that's not a ref object , so it works:
import nimpy
import nimongo / [bson, mongo]
proc fib*: seq[string] {.exportpy.} =
let m = newMongo()
if m.connect():
let col = m["feed"]["post"]
for document in col.find(%*{}).items():
result.add($document)
In python:
import nimporter
import th
for item in th.fib():
print(item)
To further illustrate, the following procs return a Table from Nim to Python: the first is a Table
, and the second a ref Table
.
import tables
import nimpy
proc objs*: Table[string, string] {.exportpy.} =
{"Nim": "Awesome"}.toTable
proc refs*: TableRef[string, string] {.exportpy.} =
{"Nim": "Awesome"}.newTable
import nimporter
import script as th
for k, v in th.objs().items():
print(k, "is", v)
for k, v in th.refs().items():
print(k, "is", v)
Only the first works, and the second is receiving a PyCapsule
that you probably didn't expect:
Nim is Awesome
Traceback (most recent call last):
File "script.py", line 8, in <module>
for k, v in th.refs().items():
TypeError: 'PyCapsule' object is not iterable
you need to translate the bson object you get into something useable in Python world. Since nimpy converts json happily into Python dicts, it makes sense to do the conversion in Nim.
Unfortunately nimongo doesn't implement a bson-json conversion, a proper answer would be to write that proc, but here's a placeholder answer that works, by decoding the bson to a string, and then encoding that as json.
th.nim
import nimpy,nimongo/bson
from json import parseJson,JsonNode
#it's important here not to import the whole of json, as %* clashes
proc toJson*(bs:Bson):JsonNode =
parseJson($bs)
proc fib(): seq[JsonNode] {.exportpy.} =
var docs = @[%*{
"double": 5436.5436,
"stringkey": "stringvalue",
"document": {
"double": 5436.5436,
"key": "value"
},
"array": [1, 2, 3],
"int32": 5436'i32,
"int64": 5436,
}]
for doc in docs:
result.add(doc.toJson)
output
{'double': 5436.5436, 'stringkey': 'stringvalue', 'document': {'double': 5436.5436, 'key': 'value'}, 'array': [1, 2, 3], 'int32': 5436, 'int64': 5436}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.