{ "info": { "author": "Ionel Cristian M\u0103rie\u0219", "author_email": "contact@ionelmc.ro", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: POSIX", "Operating System :: Unix", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Debuggers", "Topic :: Utilities" ], "description": "===========================\n python-mongoql-conv\n===========================\n\n.. image:: http://img.shields.io/travis/ionelmc/python-mongoql-conv.png\n :alt: Build Status\n :target: https://travis-ci.org/ionelmc/python-mongoql-conv\n\n.. image:: http://img.shields.io/coveralls/ionelmc/python-mongoql-conv.png\n :alt: Coverage Status\n :target: https://coveralls.io/r/ionelmc/python-mongoql-conv\n\n.. image:: http://img.shields.io/pypi/v/mongoql-conv.png\n :alt: PYPI Package\n :target: https://pypi.python.org/pypi/mongoql-conv\n\n.. image:: http://img.shields.io/pypi/dm/mongoql-conv.png\n :alt: PYPI Package\n :target: https://pypi.python.org/pypi/mongoql-conv\n\nLibrary to convert those MongoDB queries to something else, like a python\nexpresion, a function or a Django Q object tree to be used with a ORM query.\n\nFor now, only supports flat operations. No subdocuments. It might work but results are undefined/buggy. *Could be fixed\nthough ...*\n\nInstallation\n============\n\n::\n\n pip install mongoql-conv\n\nOr::\n\n pip install mongoql-conv[django]\n\nAPI\n===\n\n* ``mongoql_conv.to_string``: to_string_\n* ``mongoql_conv.to_func``: to_func_\n* ``mongoql_conv.django.to_Q``: to_Q_\n\nto_string\n=========\n\n::\n\n >>> from mongoql_conv import to_string\n\n >>> to_string({\"myfield\": 1})\n \"row['myfield'] == 1\"\n\n >>> to_string({})\n 'True'\n\n >>> set(to_string({\"field1\": 1, \"field2\": 2}).split(' and ')) == {\"(row['field2'] == 2)\", \"(row['field1'] == 1)\"}\n True\n\n >>> to_string({\"myfield\": 1}, object_name='item')\n \"item['myfield'] == 1\"\n\n >>> to_string({\"myfield\": {\"$in\": [1, 2]}})\n \"row['myfield'] in {1, 2}\"\n\n >>> to_string({\"myfield\": {\"$in\": {1: 2}}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {1: 2}. Expected one of: set, list, tuple, frozenset.\n\n >>> to_string({\"myfield\": {\"$and\": []}})\n 'True'\n\nto_string: Supported operators\n------------------------------\n\nto_string: Supported operators: Arithmetic\n``````````````````````````````````````````\n\n* **$gt**::\n\n >>> to_string({\"myfield\": {\"$gt\": 1}})\n \"row['myfield'] > 1\"\n >>> to_string({\"myfield\": {\"$gt\": [1]}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part [1]. Expected one of: int, long, float, str, unicode, bool, None.\n\n* **$gte**::\n\n >>> to_string({\"myfield\": {\"$gte\": 1}})\n \"row['myfield'] >= 1\"\n\n* **$lt**::\n\n >>> to_string({\"myfield\": {\"$lt\": 1}})\n \"row['myfield'] < 1\"\n\n* **$lte**::\n\n >>> to_string({\"myfield\": {\"$lte\": 1}})\n \"row['myfield'] <= 1\"\n\n* **$eq**::\n\n >>> to_string({\"myfield\": {\"$eq\": 1}})\n \"row['myfield'] == 1\"\n >>> to_string({\"myfield\": 1})\n \"row['myfield'] == 1\"\n\n* **$ne**::\n\n >>> to_string({\"myfield\": {\"$ne\": 1}})\n \"row['myfield'] != 1\"\n\n* **$mod**::\n\n >>> to_string({\"myfield\": {\"$mod\": [2, 1]}})\n \"row['myfield'] % 2 == 1\"\n >>> to_string({\"myfield\": {\"$mod\": [2, 1, 3]}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part [2, 1, 3]. You must have two items: divisor and remainder.\n >>> to_string({\"myfield\": {\"$mod\": 2}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 2. Expected one of: list, tuple.\n >>> to_string({\"myfield\": {\"$mod\": (2, 1)}})\n \"row['myfield'] % 2 == 1\"\n\nto_string: Supported operators: Containers\n``````````````````````````````````````````\n\n* **$in**::\n\n >>> to_string({\"myfield\": {\"$in\": (1, 2, 3)}})\n \"row['myfield'] in {1, 2, 3}\"\n\n* **$nin**::\n\n >>> to_string({\"myfield\": {\"$nin\": [1, 2, 3]}})\n \"row['myfield'] not in {1, 2, 3}\"\n >>> to_string({\"myfield\": {\"$nin\": {1: 2}}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {1: 2}. Expected one of: set, list, tuple, frozenset.\n\n* **$size**::\n\n >>> to_string({\"myfield\": {\"$size\": 3}})\n \"len(row['myfield']) == 3\"\n >>> to_string({\"myfield\": {\"$size\": \"3\"}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part '3'. Expected one of: int, long.\n\n\n* **$all**::\n\n >>> to_string({\"myfield\": {\"$all\": [1, 2, 3]}})\n \"set(row['myfield']) >= {1, 2, 3}\"\n >>> to_string({\"myfield\": {\"$all\": 1}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 1. Expected one of: set, list, tuple, frozenset.\n\n* **$exists**::\n\n >>> to_string({\"myfield\": {\"$exists\": True}})\n \"'myfield' in row\"\n >>> to_string({\"myfield\": {\"$exists\": False}})\n \"'myfield' not in row\"\n\nto_string: Supported operators: Boolean operators\n`````````````````````````````````````````````````\n\n* **$or**::\n\n >>> to_string({'$or': [{\"bubu\": {\"$gt\": 1}}, {'bubu': {'$lt': 2}}]})\n \"(row['bubu'] > 1) or (row['bubu'] < 2)\"\n >>> to_string({'$or': \"invalid value\"})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'invalid value'. Expected one of: list, tuple.\n\n* **$and**::\n\n >>> to_string({'$and': [{\"bubu\": {\"$gt\": 1}}, {'bubu': {'$lt': 2}}]})\n \"(row['bubu'] > 1) and (row['bubu'] < 2)\"\n >>> to_string({'$or': \"invalid value\"})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'invalid value'. Expected one of: list, tuple.\n\n* **$*nesting***::\n\n >>> to_string({'$and': [\n ... {\"bubu\": {\"$gt\": 1}},\n ... {'$or': [\n ... {'bubu': {'$lt': 2}},\n ... {'$and': [\n ... {'bubu': {'$lt': 3}},\n ... {'bubu': {'$lt': 4}},\n ... ]}\n ... ]}\n ... ]})\n \"(row['bubu'] > 1) and ((row['bubu'] < 2) or ((row['bubu'] < 3) and (row['bubu'] < 4)))\"\n\nto_string: Supported operators: Regular expressions\n```````````````````````````````````````````````````\n\n* **$regex**::\n\n >>> to_string({\"myfield\": {\"$regex\": 'a'}})\n \"re.search('a', row['myfield'], 0)\"\n\n >>> to_string({\"bubu\": {\"$regex\": \".*x\"}}, object_name='X')\n \"re.search('.*x', X['bubu'], 0)\"\n\n >>> to_string({\"myfield\": {\"$regex\": 'a', \"$options\": 'i'}})\n \"re.search('a', row['myfield'], 2)\"\n\n >>> closure = {}\n >>> to_string({\"bubu\": {\"$regex\": \".*x\"}}, closure=closure), closure\n (\"var0.search(row['bubu'])\", {'var0': \"re.compile('.*x', 0)\"})\n\n >>> to_string({\"myfield\": {\"$regex\": 'junk('}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid regular expression 'junk(': unbalanced parenthesis\n\n >>> to_string({\"myfield\": {\"$regex\": 'a', 'junk': 'junk'}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part \"'junk'\". You can only have `$options` with `$regex`.\n\n >>> set(to_string({\"myfield\": {\"$regex\": 'a', '$nin': ['aaa']}}).split(' and ')) == {\n ... \"(re.search('a', row['myfield'], 0))\",\n ... \"(row['myfield'] not in {'aaa'})\"\n ... }\n True\n\n >>> to_string({\"bubu\": {\"$regex\": \".*\", \"$options\": \"junk\"}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'junk'. Unsupported regex option 'j'. Only s, x, m, i are supported !\n\n >>> to_string({\"bubu\": {\"$options\": \"i\"}})\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {'$options': 'i'}. Cannot have $options without $regex.\n\nto_func\n=======\n\n::\n\n >>> from mongoql_conv import to_func\n\n >>> to_func({\"myfield\": 1}).source\n \"lambda item: (item['myfield'] == 1) # compiled from {'myfield': 1}\"\n\n >>> to_func({}).source\n 'lambda item: (True) # compiled from {}'\n\n >>> list(filter(to_func({\"myfield\": 1}), [{\"myfield\": 1}, {\"myfield\": 2}]))\n [{'myfield': 1}]\n\n >>> list(filter(to_func({}), [{\"myfield\": 1}, {\"myfield\": 2}]))\n [{'myfield': 1}, {'myfield': 2}]\n\n >>> to_func({\"myfield\": {\"$in\": [1, 2]}}).source\n \"lambda item, var0={1, 2}: (item['myfield'] in var0) # compiled from {'myfield': {'$in': [1, 2]}}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$in\": [1, 2]}}), [{\"myfield\": 1}, {\"myfield\": 2}]))\n [{'myfield': 1}, {'myfield': 2}]\n\n >>> to_func({\"myfield\": {\"$in\": {1: 2}}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {1: 2}. Expected one of: set, list, tuple, frozenset.\n\n >>> to_func({\"myfield\": {\"$and\": []}}).source\n \"lambda item: (True) # compiled from {'myfield': {'$and': []}}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$and\": []}}), [{\"myfield\": 1}, {\"myfield\": 2}]))\n [{'myfield': 1}, {'myfield': 2}]\n\n\nto_func: Supported operators\n----------------------------\n\nto_func: Supported operators: Arithmetic\n````````````````````````````````````````\n\n* **$gt**::\n\n >>> to_func({\"myfield\": {\"$gt\": 1}}).source\n \"lambda item: (item['myfield'] > 1) # compiled from {'myfield': {'$gt': 1}}\"\n >>> to_func({\"myfield\": {\"$gt\": [1]}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part [1]. Expected one of: int, long, float, str, unicode, bool, None.\n\n >>> list(filter(to_func({\"myfield\": {\"$gt\": 1}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 2}, {'myfield': 3}, {'myfield': 4}]\n\n\n* **$gte**::\n\n >>> to_func({\"myfield\": {\"$gte\": 1}}).source\n \"lambda item: (item['myfield'] >= 1) # compiled from {'myfield': {'$gte': 1}}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$gte\": 2}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 2}, {'myfield': 3}, {'myfield': 4}]\n\n* **$lt**::\n\n >>> to_func({\"myfield\": {\"$lt\": 1}}).source\n \"lambda item: (item['myfield'] < 1) # compiled from {'myfield': {'$lt': 1}}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$lt\": 1}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 0}]\n\n* **$lte**::\n\n >>> to_func({\"myfield\": {\"$lte\": 1}}).source\n \"lambda item: (item['myfield'] <= 1) # compiled from {'myfield': {'$lte': 1}}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$lte\": 1}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 0}, {'myfield': 1}]\n\n* **$eq**::\n\n >>> to_func({\"myfield\": {\"$eq\": 1}}).source\n \"lambda item: (item['myfield'] == 1) # compiled from {'myfield': {'$eq': 1}}\"\n >>> to_func({\"myfield\": 1}).source\n \"lambda item: (item['myfield'] == 1) # compiled from {'myfield': 1}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$eq\": 2}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 2}]\n\n* **$ne**::\n\n >>> to_func({\"myfield\": {\"$ne\": 1}}).source\n \"lambda item: (item['myfield'] != 1) # compiled from {'myfield': {'$ne': 1}}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$ne\": 2}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 0}, {'myfield': 1}, {'myfield': 3}, {'myfield': 4}]\n\n* **$mod**::\n\n >>> to_func({\"myfield\": {\"$mod\": [2, 1]}}).source\n \"lambda item: (item['myfield'] % 2 == 1) # compiled from {'myfield': {'$mod': [2, 1]}}\"\n >>> to_func({\"myfield\": {\"$mod\": [2, 1, 3]}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part [2, 1, 3]. You must have two items: divisor and remainder.\n\n >>> to_func({\"myfield\": {\"$mod\": 2}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 2. Expected one of: list, tuple.\n\n >>> to_func({\"myfield\": {\"$mod\": (2, 1)}}).source\n \"lambda item: (item['myfield'] % 2 == 1) # compiled from {'myfield': {'$mod': (2, 1)}}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$mod\": (2, 1)}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 1}, {'myfield': 3}]\n\nto_func: Supported operators: Containers\n````````````````````````````````````````\n\n* **$in**::\n\n >>> to_func({\"myfield\": {\"$in\": (1, 2, 3)}}).source\n \"lambda item, var0={1, 2, 3}: (item['myfield'] in var0) # compiled from {'myfield': {'$in': (1, 2, 3)}}\"\n\n >>> list(filter(to_func({\"myfield\": {\"$in\": (1, 2, 3)}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 1}, {'myfield': 2}, {'myfield': 3}]\n\n* **$nin**::\n\n >>> to_func({\"myfield\": {\"$nin\": [1, 2, 3]}}).source\n \"lambda item, var0={1, 2, 3}: (item['myfield'] not in var0) # compiled from {'myfield': {'$nin': [1, 2, 3]}}\"\n\n >>> to_func({\"myfield\": {\"$nin\": {1: 2}}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {1: 2}. Expected one of: set, list, tuple, frozenset.\n\n >>> list(filter(to_func({\"myfield\": {\"$nin\": (1, 2, 3)}}), [{\"myfield\": i} for i in range(5)]))\n [{'myfield': 0}, {'myfield': 4}]\n\n* **$size**::\n\n >>> to_func({\"myfield\": {\"$size\": 3}}).source\n \"lambda item: (len(item['myfield']) == 3) # compiled from {'myfield': {'$size': 3}}\"\n\n >>> to_func({\"myfield\": {\"$size\": \"3\"}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part '3'. Expected one of: int, long.\n\n >>> list(filter(to_func({\"myfield\": {\"$size\": 3}}), [{\"myfield\": 'x'*i} for i in range(5)]))\n [{'myfield': 'xxx'}]\n\n >>> list(filter(to_func({\"myfield\": {\"$size\": 3}}), [{\"myfield\": list(range(i))} for i in range(5)]))\n [{'myfield': [0, 1, 2]}]\n\n* **$all**::\n\n >>> to_func({\"myfield\": {\"$all\": [1, 2, 3]}}).source\n \"lambda item, var0={1, 2, 3}: (set(item['myfield']) >= var0) # compiled from {'myfield': {'$all': [1, 2, 3]}}\"\n\n >>> to_func({\"myfield\": {\"$all\": 1}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 1. Expected one of: set, list, tuple, frozenset.\n\n >>> list(filter(to_func({\"myfield\": {\"$all\": [3, 4]}}), [{\"myfield\": list(range(i))} for i in range(7)]))\n [{'myfield': [0, 1, 2, 3, 4]}, {'myfield': [0, 1, 2, 3, 4, 5]}]\n\n* **$exists**::\n\n >>> to_func({\"myfield\": {\"$exists\": True}}).source\n \"lambda item: ('myfield' in item) # compiled from {'myfield': {'$exists': True}}\"\n\n >>> to_func({\"myfield\": {\"$exists\": False}}).source\n \"lambda item: ('myfield' not in item) # compiled from {'myfield': {'$exists': False}}\"\n\n >>> list(filter(to_func({\"$or\": [{\"field1\": {\"$exists\": True}}, {\"field2\": {\"$exists\": False}}]}), [{\"field%s\" % i: i} for i in range(5)]))\n [{'field0': 0}, {'field1': 1}, {'field3': 3}, {'field4': 4}]\n\nto_func: Supported operators: Boolean operators\n```````````````````````````````````````````````\n\n* **$or**::\n\n >>> to_func({'$or': [{\"bubu\": {\"$gt\": 1}}, {'bubu': {'$lt': 2}}]}).source\n \"lambda item: ((item['bubu'] > 1) or (item['bubu'] < 2)) # compiled from {'$or': [{'bubu': {'$gt': 1}}, {'bubu': {'$lt': 2}}]}\"\n\n >>> to_func({'$or': \"invalid value\"}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'invalid value'. Expected one of: list, tuple.\n\n >>> list(filter(to_func({'$or': [{\"bubu\": {\"$gt\": 3}}, {'bubu': {'$lt': 2}}]}), [{\"bubu\": i} for i in range(5)]))\n [{'bubu': 0}, {'bubu': 1}, {'bubu': 4}]\n\n* **$and**::\n\n >>> to_func({'$and': [{\"bubu\": {\"$gt\": 1}}, {'bubu': {'$lt': 2}}]}).source\n \"lambda item: ((item['bubu'] > 1) and (item['bubu'] < 2)) # compiled from {'$and': [{'bubu': {'$gt': 1}}, {'bubu': {'$lt': 2}}]}\"\n >>> to_func({'$or': \"invalid value\"}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'invalid value'. Expected one of: list, tuple.\n >>> list(filter(to_func({'$and': [{\"bubu\": {\"$lt\": 3}}, {'bubu': {'$gt': 1}}]}), [{\"bubu\": i} for i in range(5)]))\n [{'bubu': 2}]\n\n* **$*nesting***::\n\n >>> to_func({'$and': [\n ... {\"bubu\": {\"$gt\": 1}},\n ... {'$or': [\n ... {'bubu': {'$lt': 2}},\n ... {'$and': [\n ... {'bubu': {'$lt': 3}},\n ... {'bubu': {'$lt': 4}},\n ... ]}\n ... ]}\n ... ]}).source\n \"lambda item: ((item['bubu'] > 1) and ((item['bubu'] < 2) or ((item['bubu'] < 3) and (item['bubu'] < 4)))) # compiled from {'$and': [{'bubu': {'$gt': 1}}, {'$or': [{'bubu': {'$lt': 2}}, {'$and': [{'bubu': {'$lt': 3}}, {'bubu': {'$lt': 4}}]}]}]}\"\n\nto_func: Supported operators: Regular expressions\n`````````````````````````````````````````````````\n\n* **$regex**::\n\n >>> to_func({\"myfield\": {\"$regex\": 'a'}}).source\n \"lambda item, var0=re.compile('a', 0): (var0.search(item['myfield'])) # compiled from {'myfield': {'$regex': 'a'}}\"\n\n >>> to_func({\"myfield\": {\"$regex\": 'a', \"$options\": 'i'}}).source\n \"lambda item, var0=re.compile('a', 2): (var0.search(item['myfield'])) # compiled from {'myfield': {...}}\"\n\n >>> to_func({\"myfield\": {\"$regex\": 'junk('}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid regular expression 'junk(': unbalanced parenthesis\n\n >>> to_func({\"myfield\": {\"$regex\": 'a', 'junk': 'junk'}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part \"'junk'\". You can only have `$options` with `$regex`.\n\n >>> import re\n >>> set(re.match(r'(.*): \\((.*) and (.*)\\)',\n ... to_func({\"myfield\": {\"$regex\": 'a', '$nin': ['aaa']}}, use_arguments=False).source\n ... ).groups()) == {\n ... 'lambda item',\n ... \"(item['myfield'] not in {'aaa'})\",\n ... \"(re.search('a', item['myfield'], 0))\"\n ... }\n True\n\n >>> to_func({\"bubu\": {\"$regex\": \".*\", \"$options\": \"junk\"}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'junk'. Unsupported regex option 'j'. Only s, x, m, i are supported !\n\n >>> to_func({\"bubu\": {\"$options\": \"i\"}}).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {'$options': 'i'}. Cannot have $options without $regex.\n\n >>> import string\n >>> list(filter(to_func({\"myfield\": {\"$regex\": '[a-c]', \"$options\": 'i'}}), [{\"myfield\": i} for i in string.ascii_letters]))\n [{'myfield': 'a'}, {'myfield': 'b'}, {'myfield': 'c'}, {'myfield': 'A'}, {'myfield': 'B'}, {'myfield': 'C'}]\n\n >>> list(filter(to_func({\"myfield\": {\"$regex\": '[a-c]', \"$nin\": ['c']}}), [{\"myfield\": i} for i in string.ascii_letters]))\n [{'myfield': 'a'}, {'myfield': 'b'}]\n\n >>> total = len(string.ascii_letters)\n >>> 2 * len(list(filter(\n ... to_func({\"myfield\": {\"$regex\": '[a-z]'}}),\n ... [{\"myfield\": i} for i in string.ascii_letters]\n ... ))) == total\n True\n\n >>> len(list(filter(\n ... to_func({\"myfield\": {\"$regex\": '[a-z]', '$options': 'i'}}),\n ... [{\"myfield\": i} for i in string.ascii_letters]\n ... ))) == total\n True\n\n >>> len(list(filter(\n ... to_func({\"myfield\": {\"$regex\": '[^\\d]'}}),\n ... [{\"myfield\": i} for i in string.ascii_letters]\n ... ))) == total\n True\n\n\nto_func (lax mode)\n==================\n\n::\n\n >>> from mongoql_conv import LaxNone\n >>> LaxNone < 1, LaxNone > 1, LaxNone == 0, LaxNone < 0, LaxNone > 0\n (False, False, False, False, False)\n\n >>> from mongoql_conv import to_func\n\n >>> to_func({\"myfield\": 1}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) == 1) # compiled from {'myfield': 1}\"\n\n >>> to_func({}, lax=True).source\n 'lambda item: (True) # compiled from {}'\n\n >>> list(filter(to_func({\"bogus\": 1}, lax=True), [{\"myfield\": 1}, {\"myfield\": 2}]))\n []\n\n >>> list(filter(to_func({}, lax=True), [{\"myfield\": 1}, {\"myfield\": 2}]))\n [{'myfield': 1}, {'myfield': 2}]\n\n >>> to_func({\"myfield\": {\"$in\": [1, 2]}}, lax=True).source\n \"lambda item, var0={1, 2}: ('myfield' in item and item.get('myfield', LaxNone) in var0) # compiled from {'myfield': {'$in': [1, 2]}}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$in\": [1, 2]}}, lax=True), [{\"myfield\": 1}, {\"myfield\": 2}]))\n []\n\n >>> to_func({\"myfield\": {\"$in\": {1: 2}}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {1: 2}. Expected one of: set, list, tuple, frozenset.\n\n >>> to_func({\"myfield\": {\"$and\": []}}, lax=True).source\n \"lambda item: (True) # compiled from {'myfield': {'$and': []}}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$and\": []}}, lax=True), [{\"myfield\": 1}, {\"myfield\": 2}]))\n [{'myfield': 1}, {'myfield': 2}]\n\n\nto_func (lax mode): Supported operators\n---------------------------------------\n\nto_func (lax mode): Supported operators: Arithmetic\n```````````````````````````````````````````````````\n\n* **$gt**::\n\n >>> to_func({\"myfield\": {\"$gt\": 1}}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) > 1) # compiled from {'myfield': {'$gt': 1}}\"\n >>> to_func({\"myfield\": {\"$gt\": [1]}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part [1]. Expected one of: int, long, float, str, unicode, bool, None.\n\n >>> list(filter(to_func({\"bogus\": {\"$gt\": 1}}, lax=True), [{\"myfield\": i} for i in range(5)]))\n []\n\n\n* **$gte**::\n\n >>> to_func({\"myfield\": {\"$gte\": 1}}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) >= 1) # compiled from {'myfield': {'$gte': 1}}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$gte\": 2}}, lax=True), [{\"myfield\": i} for i in range(5)]))\n []\n\n* **$lt**::\n\n >>> to_func({\"myfield\": {\"$lt\": 1}}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) < 1) # compiled from {'myfield': {'$lt': 1}}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$lt\": 1}}, lax=True), [{\"myfield\": i} for i in range(5)]))\n []\n\n* **$lte**::\n\n >>> to_func({\"myfield\": {\"$lte\": 1}}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) <= 1) # compiled from {'myfield': {'$lte': 1}}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$lte\": 1}}, lax=True), [{\"myfield\": i} for i in range(5)]))\n []\n\n* **$eq**::\n\n >>> to_func({\"myfield\": {\"$eq\": 1}}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) == 1) # compiled from {'myfield': {'$eq': 1}}\"\n >>> to_func({\"myfield\": 1}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) == 1) # compiled from {'myfield': 1}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$eq\": 2}}, lax=True), [{\"myfield\": i} for i in range(5)]))\n []\n\n* **$ne**::\n\n >>> to_func({\"myfield\": {\"$ne\": 1}}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) != 1) # compiled from {'myfield': {'$ne': 1}}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$ne\": 2}}, lax=True), [{\"myfield\": i} for i in range(5)]))\n []\n\n* **$mod**::\n\n >>> to_func({\"myfield\": {\"$mod\": [2, 1]}}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) % 2 == 1) # compiled from {'myfield': {'$mod': [2, 1]}}\"\n >>> to_func({\"myfield\": {\"$mod\": [2, 1, 3]}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part [2, 1, 3]. You must have two items: divisor and remainder.\n\n >>> to_func({\"myfield\": {\"$mod\": 2}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 2. Expected one of: list, tuple.\n\n >>> to_func({\"myfield\": {\"$mod\": (2, 1)}}, lax=True).source\n \"lambda item: (item.get('myfield', LaxNone) % 2 == 1) # compiled from {'myfield': {'$mod': (2, 1)}}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$mod\": (2, 1)}}, lax=True), [{\"myfield\": i} for i in range(5)]))\n []\n\nto_func (lax mode): Supported operators: Containers\n```````````````````````````````````````````````````\n\n* **$in**::\n\n >>> to_func({\"myfield\": {\"$in\": (1, 2, 3)}}, lax=True).source\n \"lambda item, var0={1, 2, 3}: ('myfield' in item and item.get('myfield', LaxNone) in var0) # compiled from {'myfield': {'$in': (1, 2, 3)}}\"\n\n >>> list(filter(to_func({\"bogus\": {\"$in\": (1, 2, 3)}}, lax=True), [{\"myfield\": i} for i in range(5)]))\n []\n\n* **$nin**::\n\n >>> to_func({\"myfield\": {\"$nin\": [1, 2, 3]}}, lax=True).source\n \"lambda item, var0={1, 2, 3}: ('myfield' not in item or item.get('myfield', LaxNone) not in var0) # compiled from {'myfield': {'$nin': [1, 2, 3]}}\"\n\n >>> to_func({\"myfield\": {\"$nin\": {1: 2}}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {1: 2}. Expected one of: set, list, tuple, frozenset.\n\n >>> list(filter(to_func({\"bogus\": {\"$nin\": (1, 2, 3)}}, lax=True), [{\"myfield\": i} for i in range(3)]))\n [{'myfield': 0}, {'myfield': 1}, {'myfield': 2}]\n\n* **$size**::\n\n >>> to_func({\"myfield\": {\"$size\": 3}}, lax=True).source\n \"lambda item: (len(item.get('myfield', LaxNone)) == 3) # compiled from {'myfield': {'$size': 3}}\"\n\n >>> to_func({\"myfield\": {\"$size\": \"3\"}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part '3'. Expected one of: int, long.\n\n >>> list(filter(to_func({\"bogus\": {\"$size\": 3}}, lax=True), [{\"myfield\": 'x'*i} for i in range(5)]))\n []\n\n >>> list(filter(to_func({\"bogus\": {\"$size\": 3}}, lax=True), [{\"myfield\": list(range(i))} for i in range(5)]))\n []\n\n* **$all**::\n\n >>> to_func({\"myfield\": {\"$all\": [1, 2, 3]}}, lax=True).source\n \"lambda item, var0={1, 2, 3}: (set(item.get('myfield', LaxNone)) >= var0) # compiled from {'myfield': {'$all': [1, 2, 3]}}\"\n\n >>> to_func({\"myfield\": {\"$all\": 1}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 1. Expected one of: set, list, tuple, frozenset.\n\n >>> list(filter(to_func({\"bogus\": {\"$all\": [3, 4]}}, lax=True), [{\"myfield\": list(range(i))} for i in range(7)]))\n []\n\n* **$exists**::\n\n >>> to_func({\"myfield\": {\"$exists\": True}}, lax=True).source\n \"lambda item: ('myfield' in item) # compiled from {'myfield': {'$exists': True}}\"\n\n >>> to_func({\"myfield\": {\"$exists\": False}}, lax=True).source\n \"lambda item: ('myfield' not in item) # compiled from {'myfield': {'$exists': False}}\"\n\n >>> list(filter(to_func({\"$or\": [{\"bogus\": {\"$exists\": True}}]}, lax=True), [{\"field%s\" % i: i} for i in range(5)]))\n []\n\nto_func (lax mode): Supported operators: Boolean operators\n``````````````````````````````````````````````````````````\n\n* **$or**::\n\n >>> to_func({'$or': [{\"bubu\": {\"$gt\": 1}}, {'bubu': {'$lt': 2}}]}, lax=True).source\n \"lambda item: ((item.get('bubu', LaxNone) > 1) or (item.get('bubu', LaxNone) < 2)) # compiled from {'$or': [{'bubu': {'$gt': 1}}, {'bubu': {'$lt': 2}}]}\"\n\n >>> to_func({'$or': \"invalid value\"}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'invalid value'. Expected one of: list, tuple.\n\n >>> list(filter(to_func({'$or': [{\"bogus\": {\"$gt\": 3}}, {'bogus': {'$lt': 2}}]}, lax=True), [{\"bubu\": i} for i in range(5)]))\n []\n\n* **$and**::\n\n >>> to_func({'$and': [{\"bubu\": {\"$gt\": 1}}, {'bubu': {'$lt': 2}}]}, lax=True).source\n \"lambda item: ((item.get('bubu', LaxNone) > 1) and (item.get('bubu', LaxNone) < 2)) # compiled from {'$and': [{'bubu': {'$gt': 1}}, {'bubu': {'$lt': 2}}]}\"\n >>> to_func({'$or': \"invalid value\"}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'invalid value'. Expected one of: list, tuple.\n >>> list(filter(to_func({'$and': [{\"bogus\": {\"$lt\": 3}}, {'bogus': {'$gt': 1}}]}, lax=True), [{\"bubu\": i} for i in range(5)]))\n []\n\n* **$*nesting***::\n\n >>> to_func({'$and': [\n ... {\"bubu\": {\"$gt\": 1}},\n ... {'$or': [\n ... {'bubu': {'$lt': 2}},\n ... {'$and': [\n ... {'bubu': {'$lt': 3}},\n ... {'bubu': {'$lt': 4}},\n ... ]}\n ... ]}\n ... ]}, lax=True).source\n \"lambda item: ((item.get('bubu', LaxNone) > 1) and ((item.get('bubu', LaxNone) < 2) or ((item.get('bubu', LaxNone) < 3) and (item.get('bubu', LaxNone) < 4)))) # compiled from {'$and': [{'bubu': {'$gt': 1}}, {'$or': [{'bubu': {'$lt': 2}}, {'$and': [{'bubu': {'$lt': 3}}, {'bubu': {'$lt': 4}}]}]}]}\"\n\nto_func (lax mode): Supported operators: Regular expressions\n````````````````````````````````````````````````````````````\n\n* **$regex**::\n\n >>> to_func({\"myfield\": {\"$regex\": 'a'}}, lax=True).source\n \"lambda item, var0=re.compile('a', 0): (var0.search(item.get('myfield', ''))) # compiled from {'myfield': {'$regex': 'a'}}\"\n\n >>> to_func({\"myfield\": {\"$regex\": 'a', \"$options\": 'i'}}, lax=True).source\n \"lambda item, var0=re.compile('a', 2): (var0.search(item.get('myfield', ''))) # compiled from {'myfield': {...}}\"\n\n >>> to_func({\"myfield\": {\"$regex\": 'junk('}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid regular expression 'junk(': unbalanced parenthesis\n\n >>> to_func({\"myfield\": {\"$regex\": 'a', 'junk': 'junk'}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part \"'junk'\". You can only have `$options` with `$regex`.\n\n >>> set(re.match(r'(.*): \\((.*) and (.*)\\)',\n ... to_func({\"myfield\": {\"$regex\": 'a', '$nin': ['aaa']}}, lax=True, use_arguments=False).source\n ... ).groups()) == {\n ... \"lambda item\",\n ... \"(re.search('a', item.get('myfield', ''), 0))\",\n ... \"('myfield' not in item or item.get('myfield', LaxNone) not in {'aaa'})\"\n ... }\n True\n\n >>> to_func({\"bubu\": {\"$regex\": \".*\", \"$options\": \"junk\"}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'junk'. Unsupported regex option 'j'. Only s, x, m, i are supported !\n\n >>> to_func({\"bubu\": {\"$options\": \"i\"}}, lax=True).source\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {'$options': 'i'}. Cannot have $options without $regex.\n\n >>> import string\n >>> list(filter(to_func({\"bogus\": {\"$regex\": '[a-c]', \"$options\": 'i'}}, lax=True), [{\"myfield\": i} for i in string.ascii_letters]))\n []\n\n >>> list(filter(to_func({\"bogus\": {\"$regex\": '[a-c]', \"$nin\": ['c']}}, lax=True), [{\"myfield\": i} for i in string.ascii_letters]))\n []\n\n >>> total = len(string.ascii_letters)\n >>> 2 * len(list(filter(\n ... to_func({\"bougs\": {\"$regex\": '[a-z]'}}, lax=True),\n ... [{\"myfield\": i} for i in string.ascii_letters]\n ... ))) == 0\n True\n\n >>> len(list(filter(\n ... to_func({\"bogus\": {\"$regex\": '[a-z]', '$options': 'i'}}, lax=True),\n ... [{\"myfield\": i} for i in string.ascii_letters]\n ... ))) == 0\n True\n\n >>> len(list(filter(\n ... to_func({\"bougs\": {\"$regex\": '[^\\d]'}}, lax=True),\n ... [{\"myfield\": i} for i in string.ascii_letters]\n ... ))) == 0\n True\n\n\nto_Q\n====\n\nCompiles down to a Django Q object tree::\n\n >>> from mongoql_conv.django import to_Q\n >>> print(to_Q({\"myfield\": 1}))\n (AND: ('myfield', 1))\n\n >>> print(to_Q({}))\n (AND: )\n\n >>> from test_app.models import MyModel\n >>> MyModel.objects.clean_and_create([(i, i) for i in range(5)])\n >>> MyModel.objects.filter(to_Q({\"field1\": 1}))\n []\n\n >>> MyModel.objects.filter(to_Q({\"field1\": 1, \"field2\": 1}))\n []\n\n >>> print(to_Q({\"myfield\": {\"$in\": [1, 2]}}))\n (AND: ('myfield__in', [1, 2]))\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$in\": [1, 2]}}))\n [, ]\n\n >>> print(to_Q({\"myfield\": {\"$in\": {1: 2}}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {1: 2}. Expected one of: set, list, tuple, frozenset.\n\n >>> print(to_Q({\"myfield\": {\"$and\": []}}))\n (AND: )\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$and\": []}}))\n [, , , , ]\n\n\nto_Q: Supported operators\n-------------------------\n\nto_Q: Supported operators: Arithmetic\n`````````````````````````````````````\n\n* **$gt**::\n\n >>> print(to_Q({\"myfield\": {\"$gt\": 1}}))\n (AND: ('myfield__gt', 1))\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$gt\": 2}}))\n [, ]\n\n* **$gte**::\n\n >>> print(to_Q({\"myfield\": {\"$gte\": 1}}))\n (AND: ('myfield__gte', 1))\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$gte\": 2}}))\n [, , ]\n\n* **$lt**::\n\n >>> print(to_Q({\"myfield\": {\"$lt\": 1}}))\n (AND: ('myfield__lt', 1))\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$lt\": 1}}))\n []\n\n* **$lte**::\n\n >>> print(to_Q({\"myfield\": {\"$lte\": 1}}))\n (AND: ('myfield__lte', 1))\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$lte\": 1}}))\n [, ]\n\n* **$eq**::\n\n >>> print(to_Q({\"myfield\": {\"$eq\": 1}}))\n (AND: ('myfield', 1))\n\n >>> MyModel.objects.filter(to_Q({\"field1\": 1}))\n []\n\n >>> print(to_Q({\"myfield\": 1}))\n (AND: ('myfield', 1))\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$eq\": 1}}))\n []\n\n* **$ne**::\n\n >>> str(to_Q({\"myfield\": {\"$ne\": 1}})) in [\"(NOT (AND: ('myfield', 1)))\", \"(AND: (NOT (AND: ('myfield', 1))))\"]\n True\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$ne\": 1}}))\n [, , , ]\n\n* **$mod**::\n\n >>> print(to_Q({\"myfield\": {\"$mod\": [2, 1]}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: DjangoVisitor doesn't support operator '$mod'\n\n\nto_Q: Supported operators: Containers\n`````````````````````````````````````\n\n* **$in**::\n\n >>> print(to_Q({\"myfield\": {\"$in\": (1, 2, 3)}}))\n (AND: ('myfield__in', (1, 2, 3)))\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$in\": (1, 2)}}))\n [, ]\n\n* **$nin**::\n\n >>> str(to_Q({\"myfield\": {\"$nin\": [1, 2, 3]}})) in [\"(NOT (AND: ('myfield__in', [1, 2, 3])))\", \"(AND: (NOT (AND: ('myfield__in', [1, 2, 3]))))\"]\n True\n\n >>> MyModel.objects.filter(to_Q({\"field1\": {\"$nin\": (1, 2)}}))\n [, , ]\n\n* **$size**::\n\n >>> print(to_Q({\"myfield\": {\"$size\": 3}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: DjangoVisitor doesn't support operator '$size'\n\n* **$all**::\n\n >>> print(to_Q({\"myfield\": {\"$all\": [1, 2, 3]}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: DjangoVisitor doesn't support operator '$all'\n\n* **$exists**::\n\n >>> print(to_Q({\"myfield\": {\"$exists\": True}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: DjangoVisitor doesn't support operator '$exists'\n\nto_Q: Supported operators: Boolean operators\n````````````````````````````````````````````\n\n* **$or**::\n\n >>> print(to_Q({'$or': [{\"bubu\": {\"$gt\": 1}}, {'bubu': {'$lt': 2}}]}))\n (OR: ('bubu__gt', 1), ('bubu__lt', 2))\n\n >>> MyModel.objects.filter(to_Q({'$or': [{\"field1\": {\"$gt\": 3}}, {'field1': {'$lt': 2}}]}))\n [, , ]\n\n* **$and**::\n\n >>> print(to_Q({'$and': [{\"bubu\": {\"$gt\": 1}}, {'bubu': {'$lt': 2}}]}))\n (AND: ('bubu__gt', 1), ('bubu__lt', 2))\n\n >>> MyModel.objects.filter(to_Q({'$and': [{\"field1\": {\"$gt\": 1}}, {'field1': {'$lt': 3}}]}))\n []\n\n* **$*nesting***::\n\n >>> print(to_Q({'$and': [\n ... {\"bubu\": {\"$gt\": 1}},\n ... {'$or': [\n ... {'bubu': {'$lt': 2}},\n ... {'$and': [\n ... {'bubu': {'$lt': 3}},\n ... {'bubu': {'$lt': 4}},\n ... ]}\n ... ]}\n ... ]}))\n (AND: ('bubu__gt', 1), (OR: ('bubu__lt', 2), (AND: ('bubu__lt', 3), ('bubu__lt', 4))))\n\n >>> MyModel.objects.filter(to_Q({'$and': [\n ... {\"field1\": {\"$gt\": 1}},\n ... {'$or': [\n ... {'field2': {'$lt': 2}},\n ... {'$and': [\n ... {'field2': {'$lt': 5}},\n ... {'field2': {'$gt': 2}},\n ... ]}\n ... ]}\n ... ]}))\n [, ]\n\nto_Q: Supported operators: Regular expressions\n``````````````````````````````````````````````\n\n* **$regex**::\n\n >>> print(to_Q({\"myfield\": {\"$regex\": 'a'}}))\n (AND: ('myfield__regex', 'a'))\n\n >>> print(to_Q({\"myfield\": {\"$regex\": 'a', \"$options\": 'i'}}))\n (AND: ('myfield__iregex', 'a'))\n\n >>> print(to_Q({\"myfield\": {\"$regex\": 'junk('}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid regular expression 'junk(': unbalanced parenthesis\n\n >>> print(to_Q({\"myfield\": {\"$regex\": 'a', 'junk': 'junk'}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part \"'junk'\". You can only have `$options` with `$regex`.\n\n >>> \"('myfield__regex', 'a')\" in str(to_Q({\"myfield\": {\"$regex\": 'a', '$nin': ['aaa']}}))\n True\n >>> \"(NOT (AND: ('myfield__in', ['aaa'])))\" in str(to_Q({\"myfield\": {\"$regex\": 'a', '$nin': ['aaa']}}))\n True\n\n >>> print(to_Q({\"bubu\": {\"$regex\": \".*\", \"$options\": \"mxs\"}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part 'mxs'. Unsupported regex option 'm'. Only i are supported !\n\n >>> print(to_Q({\"bubu\": {\"$options\": \"i\"}}))\n Traceback (most recent call last):\n ...\n InvalidQuery: Invalid query part {'$options': 'i'}. Cannot have $options without $regex.\n\n >>> MyModel.objects.clean_and_create([(None, \"prefix__\"+i) for i in string.ascii_letters])\n >>> MyModel.objects.filter(to_Q({\"field2\": {\"$regex\": '[a-b]', \"$options\": 'i'}}))\n [, , , ]\n\n >>> MyModel.objects.filter(to_Q({\"field2\": {\"$regex\": '[a-c]', \"$nin\": ['prefix__c']}}))\n [, ]\n\n >>> total = MyModel.objects.count()\n\n >>> total == 2 * MyModel.objects.filter(to_Q({\"field2\": {\"$regex\": '__[a-z]'}})).count()\n True\n\n >>> total == MyModel.objects.filter(to_Q({\"field2\": {\"$regex\": '__[a-z]', '$options': 'i'}})).count()\n True\n\n >>> total == MyModel.objects.filter(to_Q({\"field2\": {\"$regex\": '[^\\d]'}})).count()\n True\n\n\nExtending (implementing a custom visitor)\n=========================================\n\nThere are few requirements for a visitor. Fist, you need to be able to render boolean $and::\n\n >>> from mongoql_conv import BaseVisitor\n >>> class MyVisitor(BaseVisitor):\n ... def __init__(self, object_name):\n ... self.object_name = object_name\n ... def visit_foobar(self, value, field_name, context):\n ... return \"foobar(%s[%r], %r)\" % (self.object_name, field_name, value)\n >>> MyVisitor('obj').visit({'field': {'$foobar': 'test'}})\n Traceback (most recent call last):\n ...\n TypeError: Can't instantiate abstract class MyVisitor with abstract methods render_and\n\nThis is the minimal code to have a custom generator::\n\n >>> class MyVisitor(BaseVisitor):\n ... def __init__(self, object_name):\n ... self.object_name = object_name\n ... def visit_foobar(self, value, field_name, context):\n ... return \"foobar(%s[%r], %r)\" % (self.object_name, field_name, value)\n ... def render_and(self, parts, field_name, context):\n ... return ' & '.join(parts)\n >>> MyVisitor('obj').visit({'field': {'$foobar': 'test'}})\n \"foobar(obj['field'], 'test')\"\n\nOfcourse, it won't do much::\n\n >>> MyVisitor('obj').visit({'field': {'$ne': 'test'}})\n Traceback (most recent call last):\n ...\n InvalidQuery: MyVisitor doesn't support operator '$ne'\n\nTake a look at ``ExprVisitor`` too see all the methods you *should* implement.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ionelmc/python-mongoql-conv", "keywords": "mongo,mongodb,django,orm,query,conversion,converter", "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "mongoql-conv", "package_url": "https://pypi.org/project/mongoql-conv/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/mongoql-conv/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/ionelmc/python-mongoql-conv" }, "release_url": "https://pypi.org/project/mongoql-conv/0.4.1/", "requires_dist": null, "requires_python": null, "summary": "Library to convert those MongoDB queries to something else, like a python expresion, a function or a Django Q object tree to be used with a ORM query.", "version": "0.4.1" }, "last_serial": 1110465, "releases": { "0.0.1": [], "0.1.0": [ { "comment_text": "", "digests": { "md5": "89d9a840fe19525aa1aa063371f483bc", "sha256": "3bc1775ec42cdcad51ef9a3e95df5b53f4cef60ba578592bdb5954f821f0e87b" }, "downloads": -1, "filename": "mongoql-conv-0.1.0.tar.gz", "has_sig": false, "md5_digest": "89d9a840fe19525aa1aa063371f483bc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21456, "upload_time": "2014-01-12T17:35:42", "url": "https://files.pythonhosted.org/packages/63/6f/60ca89c9659594d9b86c97c7acb81e7e0c142592fbf4f48a6614bc1d8705/mongoql-conv-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "a7e954138f77d5a5c5c2590104289d83", "sha256": "37c21f913020db9c396d39aa77505a85fbea060b2b71bb54061bde39c35072f6" }, "downloads": -1, "filename": "mongoql-conv-0.1.1.tar.gz", "has_sig": false, "md5_digest": "a7e954138f77d5a5c5c2590104289d83", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21678, "upload_time": "2014-01-13T08:37:29", "url": "https://files.pythonhosted.org/packages/ef/92/5ded12b62b89f56628af7ef42c075e12408d35b396bf69c001406a6f505b/mongoql-conv-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "8ed9671438c0aa2bb71d8fb747d1037a", "sha256": "268039ab53dbc1ffe73985c8cfbf6590de910c32eb4a51d1be4d4ff5542f549f" }, "downloads": -1, "filename": "mongoql-conv-0.2.0.tar.gz", "has_sig": false, "md5_digest": "8ed9671438c0aa2bb71d8fb747d1037a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22121, "upload_time": "2014-01-13T10:53:06", "url": "https://files.pythonhosted.org/packages/f9/61/c13316c6ad86d1d6bdf1fc0bbfaf38625079a14229e81db1cd328e1cb2b7/mongoql-conv-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "a223bf3f3af6a9029a7ad70f1101dc66", "sha256": "d5bb56474b1c09d62bd61206505734c770222dd161c8397eabcd13ebfb8f646b" }, "downloads": -1, "filename": "mongoql-conv-0.2.1.tar.gz", "has_sig": false, "md5_digest": "a223bf3f3af6a9029a7ad70f1101dc66", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22121, "upload_time": "2014-01-13T10:55:01", "url": "https://files.pythonhosted.org/packages/e3/d3/8720f3487af85675650e5743e0a149620b06d39e84df980def5de6ff3ec2/mongoql-conv-0.2.1.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "fd73e2e466e0163f45b9911593d60971", "sha256": "fc846ee8cc1a1c6d41ed0d7207051e417e170b7f276662772f23e7a6e71b1adf" }, "downloads": -1, "filename": "mongoql-conv-0.3.0.tar.gz", "has_sig": false, "md5_digest": "fd73e2e466e0163f45b9911593d60971", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23018, "upload_time": "2014-02-04T13:19:59", "url": "https://files.pythonhosted.org/packages/5f/fc/bffdacb76b06932abef21073ed6cd03240ec0e7ade29124d4b536d5ea7b5/mongoql-conv-0.3.0.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "65c121f9445b4b3e9a829a4d341f2145", "sha256": "64f0d6ee118d71c3466bfc60d5353622fd5d73468a99bcf579f9898a5c9174cb" }, "downloads": -1, "filename": "mongoql-conv-0.4.0.tar.gz", "has_sig": false, "md5_digest": "65c121f9445b4b3e9a829a4d341f2145", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22747, "upload_time": "2014-05-12T09:14:14", "url": "https://files.pythonhosted.org/packages/ff/fe/d298e8ed714f7da6ab1b1a08605bb95011f379689a7e97496af0f3b9572a/mongoql-conv-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "acce5cd1ec3c701c1aa02640599de9fe", "sha256": "f643dba47909e38414d39e1a10f21bf66d7d86bcb1ca0b327cd7d9f76f07352d" }, "downloads": -1, "filename": "mongoql_conv-0.4.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "acce5cd1ec3c701c1aa02640599de9fe", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 16008, "upload_time": "2014-06-01T17:27:03", "url": "https://files.pythonhosted.org/packages/46/d8/524f40dcb1612750f29b9fea41e992877ad71e30a76d31ba4fbb844b3bc0/mongoql_conv-0.4.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c74ca702aa7580a5eb79beac7d696541", "sha256": "0f9697faed8ccea4fac39f0d8be23445f4a6e860692a1e23375208988a17aa32" }, "downloads": -1, "filename": "mongoql-conv-0.4.1.tar.gz", "has_sig": false, "md5_digest": "c74ca702aa7580a5eb79beac7d696541", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25000, "upload_time": "2014-06-01T17:27:01", "url": "https://files.pythonhosted.org/packages/1d/87/5cdfb17cd811267e61f5c99a7d7e66980e274d7dc0cfe2aec0baa0225df2/mongoql-conv-0.4.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "acce5cd1ec3c701c1aa02640599de9fe", "sha256": "f643dba47909e38414d39e1a10f21bf66d7d86bcb1ca0b327cd7d9f76f07352d" }, "downloads": -1, "filename": "mongoql_conv-0.4.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "acce5cd1ec3c701c1aa02640599de9fe", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 16008, "upload_time": "2014-06-01T17:27:03", "url": "https://files.pythonhosted.org/packages/46/d8/524f40dcb1612750f29b9fea41e992877ad71e30a76d31ba4fbb844b3bc0/mongoql_conv-0.4.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c74ca702aa7580a5eb79beac7d696541", "sha256": "0f9697faed8ccea4fac39f0d8be23445f4a6e860692a1e23375208988a17aa32" }, "downloads": -1, "filename": "mongoql-conv-0.4.1.tar.gz", "has_sig": false, "md5_digest": "c74ca702aa7580a5eb79beac7d696541", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25000, "upload_time": "2014-06-01T17:27:01", "url": "https://files.pythonhosted.org/packages/1d/87/5cdfb17cd811267e61f5c99a7d7e66980e274d7dc0cfe2aec0baa0225df2/mongoql-conv-0.4.1.tar.gz" } ] }