{ "info": { "author": "Nicholas Repole", "author_email": "n.repole@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Database :: Front-Ends" ], "description": "MQLAlchemy\r\n==========\r\n\r\n|Build Status| |Coverage Status| |Docs|\r\n\r\nQuery SQLAlchemy models using MongoDB style syntax.\r\n\r\nWhy?\r\n----\r\n\r\nThe need arose for me to be able to pass complex database filters from\r\nclient side JavaScript to a Python server. I started building some JSON\r\nstyle syntax to do so, then realized such a thing already existed. I\u2019ve\r\nnever seriously used MongoDB, but the syntax for querying lends itself\r\npretty perfectly to this use case.\r\n\r\n**That sounds pretty dangerous\u2026**\r\n\r\nIt can be. When using this with any sort of user input, you\u2019ll want to\r\npass in a whitelist of attributes that are ok to query, otherwise you\u2019ll\r\nopen the possibility of leaked passwords and all sorts of other scary\r\nstuff.\r\n\r\n**So, can I actually use this for a serious project?**\r\n\r\nMaybe? There\u2019s some decent test coverage, but this certainly isn\u2019t a\r\nvery mature project yet.\r\n\r\nI\u2019ll be pretty active in supporting this, so if you are using this and\r\nrun into problems, I should be pretty quick to fix them.\r\n\r\n**How fast is it?**\r\n\r\nI\u2019m sure my actual syntax parsing is inefficient and has loads of room\r\nfor improvement, but the time it takes to parse should be minimal\r\ncompared to the actual database query, so this shouldn\u2019t slow your\r\nqueries down too much.\r\n\r\nSupported Operators\r\n-------------------\r\n\r\n- $and\r\n- $or\r\n- $not\r\n- $nor\r\n- $in\r\n- $nin\r\n- $gt\r\n- $gte\r\n- $lt\r\n- $lte\r\n- $ne\r\n- $mod\r\n\r\nCustom operators added for convenience: \r\n\r\n- $eq - Explicit equality check.\r\n- $like - Search a text field for the given value.\r\n\r\nNot yet supported, but would like to add:\r\n\r\n- Index based relation queries. Album.tracks.0.track_id won\u2019t work.\r\n- $regex\r\n\r\nExamples\r\n--------\r\n\r\n.. code:: python\r\n\r\n from sqlalchemy import create_engine\r\n from sqlalchemy.orm import sessionmaker\r\n from mqlalchemy import apply_mql_filters\r\n from myapp.mymodels import Album\r\n\r\n # get your sqlalchemy db session here\r\n db_engine = create_engine(\"sqlite+pysqlite:///mydb.sqlite\")\r\n DBSession = sessionmaker(bind=db_engine)\r\n db_session = DBSession()\r\n\r\n # define which fields of Album are ok to query\r\n whitelist = [\"album_id\", \"artist.name\", \"tracks.playlists.name\"]\r\n # Find all albums that are either by Led Zeppelin or have a track \r\n # that can be found on the \"Grunge\" playlist.\r\n filters = {\r\n \"$or\": [\r\n {\"tracks.playlists.name\": \"Grunge\"},\r\n {\"artist.name\": \"Led Zeppelin\"}\r\n ]\r\n }\r\n query = apply_mql_filters(db_session, Album, filters, whitelist)\r\n matching_records = query.all()\r\n\r\nFor more, please see the included tests, as they're probably the\r\neasiest way to get an idea of how the library can be used.\r\n\r\nContributing\r\n------------\r\n\r\nSubmit a pull request and make sure to include an updated AUTHORS \r\nwith your name along with an updated CHANGES.rst.\r\n\r\nLicense\r\n-------\r\n\r\nMIT\r\n\r\n.. |Build Status| image:: https://travis-ci.org/repole/mqlalchemy.svg?branch=master\r\n :target: https://travis-ci.org/repole/mqlalchemy\r\n.. |Coverage Status| image:: https://coveralls.io/repos/repole/mqlalchemy/badge.svg?branch=master\r\n :target: https://coveralls.io/r/repole/mqlalchemy?branch=master\r\n.. |Docs| image:: https://readthedocs.org/projects/mqlalchemy/badge/?version=latest\r\n :target: http://mqlalchemy.readthedocs.org/en/latest/\r\n\r\n", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/repole/mqlalchemy/tarball/0.2.0", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/repole/mqlalchemy", "keywords": "mongodb,sqlalchemy,json,sql", "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "MQLAlchemy", "package_url": "https://pypi.org/project/MQLAlchemy/", "platform": "any", "project_url": "https://pypi.org/project/MQLAlchemy/", "project_urls": { "Download": "https://github.com/repole/mqlalchemy/tarball/0.2.0", "Homepage": "https://github.com/repole/mqlalchemy" }, "release_url": "https://pypi.org/project/MQLAlchemy/0.2.0/", "requires_dist": null, "requires_python": null, "summary": "Query SQLAlchemy models with MongoDB syntax.", "version": "0.2.0" }, "last_serial": 1996821, "releases": { "0.1.3": [ { "comment_text": "", "digests": { "md5": "2f52e754d72935006bc149668346907d", "sha256": "7d8ff076e8b9c34ac4bda6f25ac44d190f86d064f5514ac3f51574c46b79f48f" }, "downloads": -1, "filename": "MQLAlchemy-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "2f52e754d72935006bc149668346907d", "packagetype": "bdist_wheel", "python_version": "3.3", "requires_python": null, "size": 12569, "upload_time": "2015-03-28T17:16:20", "url": "https://files.pythonhosted.org/packages/4a/26/310ddbae1ac1ed5cf6782208156f3ef71873416be599aafdeb74c72a82ec/MQLAlchemy-0.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "89293054f9c6fe5dbb2897d0bc3f6bf6", "sha256": "f55e6062f261eab7d0748f9e761799184b7fce2d27f1d094bc62c52e345f5ce2" }, "downloads": -1, "filename": "MQLAlchemy-0.1.3.zip", "has_sig": false, "md5_digest": "89293054f9c6fe5dbb2897d0bc3f6bf6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 390194, "upload_time": "2015-03-28T17:16:18", "url": "https://files.pythonhosted.org/packages/90/08/92db38edeaac233c863f53977c4044679b5f1d2dfca5d2711fe5593d29d8/MQLAlchemy-0.1.3.zip" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "e261f7d8bdca6168e120098832def7d6", "sha256": "256df6bb2e67633464da3133f2486165fefcc24f67b2761d427d29f926b7e0ad" }, "downloads": -1, "filename": "MQLAlchemy-0.1.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e261f7d8bdca6168e120098832def7d6", "packagetype": "bdist_wheel", "python_version": "3.3", "requires_python": null, "size": 13408, "upload_time": "2015-11-15T03:48:31", "url": "https://files.pythonhosted.org/packages/72/6b/8ee3bb601d0732e707a10d0f93a1f59b437a60431c919c9d60eee3bf70ab/MQLAlchemy-0.1.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e0c656baefc5a8bfa19cb91bf3c2b3e7", "sha256": "52a3e96dc9b7aa2241d06d8a69747b40d088afad1ec6d4c53e216f5e46c2fe36" }, "downloads": -1, "filename": "MQLAlchemy-0.1.4.zip", "has_sig": false, "md5_digest": "e0c656baefc5a8bfa19cb91bf3c2b3e7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 390892, "upload_time": "2015-11-15T03:48:26", "url": "https://files.pythonhosted.org/packages/9a/53/bcf8bf9ec63e5077fa8a0e20f1417647a6863f01fdc90381fedd064f1df0/MQLAlchemy-0.1.4.zip" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "b11604950de8957a3acaab00e5aecaf0", "sha256": "0a96a359646ee5e66db05409768fd1e2a02269af52835166c3875e0fbf1950e3" }, "downloads": -1, "filename": "MQLAlchemy-0.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b11604950de8957a3acaab00e5aecaf0", "packagetype": "bdist_wheel", "python_version": "3.3", "requires_python": null, "size": 14264, "upload_time": "2016-03-09T05:07:20", "url": "https://files.pythonhosted.org/packages/fb/fa/60465750f90d647911fd948c11f702dc20617075e8fad08047215e2cd726/MQLAlchemy-0.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d1b102f1a67c64bfad6f8b84c312bb01", "sha256": "279aaecaf867f91ab6381e3602ea2d5927c27ca4af6496a045f49499f60368c6" }, "downloads": -1, "filename": "MQLAlchemy-0.2.0.zip", "has_sig": false, "md5_digest": "d1b102f1a67c64bfad6f8b84c312bb01", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 391809, "upload_time": "2016-03-09T05:07:14", "url": "https://files.pythonhosted.org/packages/11/ee/6f41bb280e3e81fc43a6ad13a0593b0f7eb94445dd37f3f73dadf51dd833/MQLAlchemy-0.2.0.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "b11604950de8957a3acaab00e5aecaf0", "sha256": "0a96a359646ee5e66db05409768fd1e2a02269af52835166c3875e0fbf1950e3" }, "downloads": -1, "filename": "MQLAlchemy-0.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b11604950de8957a3acaab00e5aecaf0", "packagetype": "bdist_wheel", "python_version": "3.3", "requires_python": null, "size": 14264, "upload_time": "2016-03-09T05:07:20", "url": "https://files.pythonhosted.org/packages/fb/fa/60465750f90d647911fd948c11f702dc20617075e8fad08047215e2cd726/MQLAlchemy-0.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d1b102f1a67c64bfad6f8b84c312bb01", "sha256": "279aaecaf867f91ab6381e3602ea2d5927c27ca4af6496a045f49499f60368c6" }, "downloads": -1, "filename": "MQLAlchemy-0.2.0.zip", "has_sig": false, "md5_digest": "d1b102f1a67c64bfad6f8b84c312bb01", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 391809, "upload_time": "2016-03-09T05:07:14", "url": "https://files.pythonhosted.org/packages/11/ee/6f41bb280e3e81fc43a6ad13a0593b0f7eb94445dd37f3f73dadf51dd833/MQLAlchemy-0.2.0.zip" } ] }