{ "info": { "author": "Suyash Soni", "author_email": "suyash.soni248@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# Sqlalchemy JSON Querybuilder\n\nIt introduces a middleware between your application and Sqlalchemy ORM. So input to ORM can be provided in the form JSON/Objects.\n\n## Installation\n\n```sh\npip install sqlalchemy-json-querybuilder\n```\n\n## Features\n\n- Multiple [operators](https://github.com/suyash248/sqlalchemy-json-querybuilder/blob/master/README.md#operators)' support.\n - Support for [Filter operators](http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#common-filter-operators).\n - Support for [Relationship operators](http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#common-relationship-operators) i.e. `any`, `has`.\n\n- Filter in relationship as well as in collections.\n\n- Pagination using windowing & slicing. Pagination can be disabled if needed.\n\n- Ordering/Sorting in `ASC` & `DESC` order.\n\n- Supports `AND` & `OR`, so multiple query criterion can be glued and bundled using `AND` or `OR` as follows -\n ```python\n criteria = {\n 'and': [and_criterion_dict_1, and_criterion_dict_2, ... and_criterion_dict_n],\n 'or': [or_criterion_dict_1, or_criterion_dict_2, ... or_criterion_dict_n]\n }\n ```\n\n which is equivalent to - \n\n ```sql\n SELECT field_1, field_2..field_n FROM some_table WHERE\n (and_criterion_dict_1 AND and_criterion_dict_1 AND and_criterion_dict_n)\n AND\n (or_criterion_dict_1 OR or_criterion_dict_1 OR or_criterion_dict_1);\n ```\n\n## Usage\n\n- #### Filter criteria\n\n ```python\n\n # Each criterion has 3 attributes: field_name, operator, field_value\n\n criterion_1 = {\n 'field_name': 'MyModel1.some_field',\n 'operator': 'some_operator' # Supported operators are listed below\n 'field_value': 'some_value'\n }\n\n # Once all the critera are defined in the form of dictionary/object, bundle them as follows -\n\n filter_by = {\n 'and': [criterion_1, criterion_2,....criterion_n],\n 'or': [other_criterion_1, other_criterion_2,....other_criterion_n]\n }\n\n # If there are `and` critera only, then they can be bundled in following 2 ways -\n filter_by = [criterion_1, criterion_2,....criterion_n] \n\n # Alternative way to bundle `and` criteria\n filter_by = {\n 'and': [criterion_1, criterion_2,....criterion_n]\n }\n\n # If there are `or` critera only, then they can be bundled as -\n filter_by = {\n 'or': [criterion_1, criterion_2,....criterion_n]\n }\n\n ```\n\n- #### Ordering\n\n ```python\n ordering = ['MyModel1.some_field', '-MyModel1.other_field'] # `-` sign indicates DESC order.\n ```\n\n- #### Pagination\n\n Following 3 attributes are used to control pagination:\n\n - `page`: Current page number.\n - `per_page`: Number of records to be displayed on a page.\n - `all`: Defaults to `False`, make it `True` in order to disable the pagination and fetch all records at once.\n\n- #### Querying\n\n ```python\n from sqlalchemy_json_querybuilder.querybuilder.search import Search\n\n # session - SqlAlchemy session\n # 'some_module.models' - Package/module where all the models are placed.\n search_obj = Search(session, 'some_module.models', (MyModel1,), filter_by=criteria, \n order_by=ordering, page=1, per_page=10, all=False)\n\n # Results contains `data` & `count`\n results = search_obj.results\n ```\n\n## Operators\n\nFollowing operators are supported - \n\n`equals`, `eq`, `==`, `=`,\n\n`not_equals`, `ne`, `!=`, `~=`,\n\n`less_than`, `lt`, `<`,\n\n`less_than_equals`, `lte`, `<=`,\n\n`greater_than`, `gt`, `>`,\n\n`greater_than_equals`, `gte`, `>=`,\n\n`like`, `ilike`, \n\n`startswith`, `istartswith`, `endswith`, `iendswith`, \n\n`contains`, `icontains`, \n\n`match`, \n\n`in`, `notin`, \n\n`isnull`, `isnotnull`, \n\n`any`, `has`\n\n> Note - `i` stands for `case insensitive`.\n\n- #### equals\n\n ```python\n filter_by = [dict(field_name='User.name', field_value='ed', operator='equals')]\n ```\n is translated to\n\n ```python\n query.filter(User.name == 'ed')\n ```\n\n- #### notequals\n\n ```python\n filter_by = [dict(field_name='User.name', field_value='ed', operator='not_equals')]\n ```\n is translated to\n\n ```python\n query.filter(User.name != 'ed')\n ```\n\n- #### lt\n\n ```python\n filter_by = [dict(field_name='User.age', field_value=18, operator='lt')]\n ```\n is translated to\n\n ```python\n query.filter(User.age < 18)\n ```\n\n- #### lte\n\n ```python\n filter_by = [dict(field_name='User.age', field_value=18, operator='lte')]\n ```\n is translated to\n\n ```python\n query.filter(User.age <= 18)\n ```\n\n- #### gt\n\n ```python\n filter_by = [dict(field_name='User.age', field_value=18, operator='gt')]\n ```\n is translated to\n\n ```python\n query.filter(User.age > 18)\n ```\n\n- #### gte\n\n ```python\n filter_by = [dict(field_name='User.age', field_value=18, operator='gte')]\n ```\n is translated to\n\n ```python\n query.filter(User.age >= 18)\n ```\n\n- #### in\n\n ```python\n filter_by = [dict(field_name='User.name', field_value=['ed', 'wendy', 'jack'], operator='in')]\n ```\n is translated to\n\n ```python\n query.filter(User.name.in_(['ed', 'wendy', 'jack']))\n ```\n\n- #### notin\n\n ```python\n filter_by = [dict(field_name='User.name', field_value=['ed', 'wendy', 'jack'], operator='notin')]\n ```\n is translated to\n\n ```python\n query.filter(~User.name.in_(['ed', 'wendy', 'jack']))\n ```\n\n- #### isnull\n\n ```python\n filter_by = [dict(field_name='User.name', field_value=null, operator='isnull')]\n ```\n is translated to\n\n ```python\n query.filter(User.name == None)\n\n # alternatively, if pep8/linters are a concern\n query.filter(User.name.is_(None))\n ```\n\n- #### isnotnull\n\n ```python\n filter_by = [dict(field_name='User.name', field_value=null, operator='isnotnull')]\n ```\n\n is translated to\n\n ```python\n query.filter(User.name != None)\n\n # alternatively, if pep8/linters are a concern\n query.filter(User.name.isnot(None))\n ```\n\n- #### contains\n\n ```python\n filter_by = [dict(field_name='User.name', field_value='ed', operator='contains')]\n ```\n is translated to\n\n ```python\n query.filter(User.name.like('%ed%'))\n ```\n\n- #### startswith\n\n ```python\n filter_by = [dict(field_name='User.name', field_value='ed', operator='startswith')]\n ```\n is translated to\n\n ```python\n query.filter(User.name.like('ed%'))\n ```\n\n- #### endswith\n\n ```python\n filter_by = [dict(field_name='User.name', field_value='ed', operator='endswith')]\n ```\n is translated to\n\n ```python\n query.filter(User.name.like('%ed'))\n ```\n\n- #### match\n\n ```python\n filter_by = [dict(field_name='User.name', field_value='wendy', operator='match')]\n ```\n is translated to\n\n ```python\n query.filter(User.name.match('wendy'))\n ```\n\n- #### any\n\n ```python\n filter_by = [{\n 'field_name': 'User.addresses',\n 'operator': 'any',\n 'field_value': {\n 'field_name': 'Address.email_address',\n 'operator': 'equals',\n 'field_value': 'bar'\n }\n }]\n ```\n is translated to\n\n ```python\n query.filter(User.addresses.any(Address.email_address == 'bar'))\n\n # also takes keyword arguments:\n query.filter(User.addresses.any(email_address='bar'))\n ```\n\n- #### has\n\n ```python\n filter_by = [{\n 'field_name': 'Address.user',\n 'operator': 'has',\n 'field_value': {\n 'field_name': 'User.name',\n 'operator': 'equals',\n 'field_value': 'bar'\n }\n }]\n ```\n is translated to\n\n ```python\n query.filter(Address.user.has(name='ed'))\n ```\n\n## Examples\n\nSome examples are given below. More examples can be found [here](https://github.com/suyash248/sqlalchemy-json-querybuilder/blob/master/examples/main.py).\n\n\n```python\n\n#-------------- Creating connection & session ---------------#\n\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker, scoped_session\n\nBase = declarative_base()\ncon_url = 'mysql+pymysql://{username}:{password}@{host}:{port}/{database}'.format(\n username='root', password='', host='localhost', port=3306, database='test'\n)\nengine = create_engine(con_url, pool_recycle=3600)\n\n# Set up the session\nsession_maker = sessionmaker(bind=engine, autoflush=True, autocommit=False, expire_on_commit=True)\nsession = scoped_session(session_maker)\n\n#-------------- Models ---------------#\n\nfrom uuid import uuid4\nfrom sqlalchemy import Column, Integer, String, Text, ForeignKey\nfrom sqlalchemy.orm import relationship\n\ndef generate_uuid():\n return str(uuid4())\n\nclass NotificationGroup(Base):\n __tablename__ = \"notification_group\"\n\n id = Column(\"id\", String(75), primary_key=True, default=generate_uuid)\n client_id = Column('client_id', Integer, nullable=False)\n denotation = Column('denotation', String(250), nullable=False) \n description = Column('description', String(500))\n customers_sites = Column('customers_sites', Text, nullable=False)\n group_mappings = relationship(\"NotificationGroupMapping\", backref=\"notification_group_mapping\", lazy='dynamic')\n\nclass NotificationGroupMapping(Base):\n __tablename__ = \"notification_group_mapping\"\n\n id = Column(\"id\", String(75), primary_key=True, default=generate_uuid)\n notification_group_id = Column(String(75), ForeignKey('notification_group.id'))\n event_id = Column(String(75), nullable=False)\n recipient_id = Column(String(75), ForeignKey('recipient_group.id'))\n recipient = relationship(\"Recipient\")\n is_used = Column(String(75), nullable=False)\n\nclass Recipient(Base):\n __tablename__ = 'recipients'\n\n client_id = Column('client_id', Integer, nullable=False)\n user_id = Column('user_id', Integer, nullable=False)\n email = Column('email', String(256), nullable=False)\n\n#-------------- Query -------------#\n\nfrom sqlalchemy_json_querybuilder.querybuilder.search import Search\n\n# `filter_by` can have multiple criteria objects bundled as a list.\nfilter_by = [{\n \"field_name\": \"NotificationGroup.group_mappings\",\n \"field_value\": {\n \"field_name\": \"NotificationGroupMapping.recipient\",\n \"field_value\": {\n \"field_name\": \"Recipient.email\",\n \"field_value\": \"Sam@gmail.com\",\n \"operator\": \"equals\"\n },\n \"operator\": \"has\"\n },\n \"operator\": \"any\"\n}]\n\n# `order_by` can have multiple column names. `-` indicates arranging the results in `DESC` order.\norder_by = ['-NotificationGroup.client_id']\n\n# returns `results` dict containing `data` & `count`\nresults = Search(session, \"models.notification_group\", (NotificationGroup,), \n filter_by=filter_by, order_by=order_by, page=1, per_page=5).results\n\n# Above code snippet is equivalent to\n\nresults = session.query(NotificationGroup).filter(\n NotificationGroup.group_mappings.any(\n NotificationGroupMapping.recipient.has(\n Recipient.email=='Sam@gmail.com'\n )\n )\n ).all()\n\n```\n\n## Contributions\n\nPull requests are welcome! Please create new pull requests from `dev` branch.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/suyash248/sqlalchemy-json-querybuilder", "keywords": "", "license": "", "maintainer": "Suyash Soni", "maintainer_email": "", "name": "sqlalchemy-json-querybuilder", "package_url": "https://pypi.org/project/sqlalchemy-json-querybuilder/", "platform": "", "project_url": "https://pypi.org/project/sqlalchemy-json-querybuilder/", "project_urls": { "Homepage": "https://github.com/suyash248/sqlalchemy-json-querybuilder" }, "release_url": "https://pypi.org/project/sqlalchemy-json-querybuilder/1.2.3/", "requires_dist": [ "sqlalchemy" ], "requires_python": ">=3", "summary": "Querybuilder to use SqlAlchemy ORM by feeding JSON/object as input", "version": "1.2.3" }, "last_serial": 3999510, "releases": { "1.1.6": [ { "comment_text": "", "digests": { "md5": "80862b2209f05f0695053360ebf604fa", "sha256": "63af3bb698caef1d9955f86a5e2d1c7adc9d916790d217cbd9ec2d436ab76f1b" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.1.6-py3-none-any.whl", "has_sig": false, "md5_digest": "80862b2209f05f0695053360ebf604fa", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 13358, "upload_time": "2018-06-23T07:18:58", "url": "https://files.pythonhosted.org/packages/a7/75/9a2fec2733d3f0bc86be4fe2a11696550187b1b3301d307b3d11bf56dac3/sqlalchemy_json_querybuilder-1.1.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "61b90cf5d7e058fdf912dd6286e0e935", "sha256": "b9b77dd4d01359fa6297f90c33fc8148aa7badf75e4314c8fb631cff40074432" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.1.6.tar.gz", "has_sig": false, "md5_digest": "61b90cf5d7e058fdf912dd6286e0e935", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 11283, "upload_time": "2018-06-23T07:19:00", "url": "https://files.pythonhosted.org/packages/a4/22/ba5d380b0d7b06b7799b145f7587b1e0f2ba611405a45bf2eef9ca9a3ca5/sqlalchemy_json_querybuilder-1.1.6.tar.gz" } ], "1.1.7": [ { "comment_text": "", "digests": { "md5": "c0c334fe9748a217e05a718a405afef6", "sha256": "3bf2c52946fc1800bcd98ab059b8b4c3771b69a2ee02e552bd5603de442893dd" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.1.7-py3-none-any.whl", "has_sig": false, "md5_digest": "c0c334fe9748a217e05a718a405afef6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 13358, "upload_time": "2018-06-23T07:31:44", "url": "https://files.pythonhosted.org/packages/45/a4/f3c5468f00791a3f948f62c20e24f91cf968b0747a1d875002bce82293e9/sqlalchemy_json_querybuilder-1.1.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b343192ed5f381b1b12c3708518c055a", "sha256": "086f895b5cd3b2a34a2c26398f33e7519951d79d484d8394d50c5f08fefacb5a" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.1.7.tar.gz", "has_sig": false, "md5_digest": "b343192ed5f381b1b12c3708518c055a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 11288, "upload_time": "2018-06-23T07:31:46", "url": "https://files.pythonhosted.org/packages/df/c0/2c3d8322f48173cbce0318a78a1c050ff5ffe6b2e9d9c0b0be84e8d70bcb/sqlalchemy_json_querybuilder-1.1.7.tar.gz" } ], "1.1.8": [ { "comment_text": "", "digests": { "md5": "515bb8737fe312c6fe842cdd1ff11492", "sha256": "3ba3c45c6e51cc3971e72de6b07a2dcac0da2ebe0ef4d1f80b5bc3bf5839a624" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.1.8-py3-none-any.whl", "has_sig": false, "md5_digest": "515bb8737fe312c6fe842cdd1ff11492", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 13365, "upload_time": "2018-06-23T07:39:04", "url": "https://files.pythonhosted.org/packages/00/10/4d18302799ee2d41aaf135110ca87590af2cd0666ff0d95c4ffbea5f3110/sqlalchemy_json_querybuilder-1.1.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4dbff6a21430859d07e90fbc47bbe920", "sha256": "cb80b3eeed81cf0d974972f4bed6ea74ccb05f72b3b1bbfd168458e368d7e701" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.1.8.tar.gz", "has_sig": false, "md5_digest": "4dbff6a21430859d07e90fbc47bbe920", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 11294, "upload_time": "2018-06-23T07:39:06", "url": "https://files.pythonhosted.org/packages/80/60/10fdff925ef8d71bfc9a13fc5223cb31afad72760de7de1585776261a913/sqlalchemy_json_querybuilder-1.1.8.tar.gz" } ], "1.1.9": [ { "comment_text": "", "digests": { "md5": "aec4dd3ecc07ae365c7721c1d0311e23", "sha256": "9ad3d785623d22ad1a6649e91a2e522ff9860c841431093ffa2080bcbbd03491" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.1.9-py3-none-any.whl", "has_sig": false, "md5_digest": "aec4dd3ecc07ae365c7721c1d0311e23", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 14388, "upload_time": "2018-06-23T15:50:47", "url": "https://files.pythonhosted.org/packages/11/a0/1702c0abe1a2eeb013a9c4b91d7ec82731e7848efee67176c94bf058ecaa/sqlalchemy_json_querybuilder-1.1.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "960d506f459cd866b4adfaf177015997", "sha256": "9ab51f7eae7fbbe7101646938690ce73b5d82b899ac004d75557cf14d52bb443" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.1.9.tar.gz", "has_sig": false, "md5_digest": "960d506f459cd866b4adfaf177015997", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 13178, "upload_time": "2018-06-23T15:50:49", "url": "https://files.pythonhosted.org/packages/2f/36/ec21d72e871c7aaabd43c55b469b4a1d088480cc115b30fdc16d85f66f0c/sqlalchemy_json_querybuilder-1.1.9.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "8aee88187ec429dc9d821408bc3565bf", "sha256": "4b33edfc6b69db8e2b962525bfef499e6585d2092a37661c60343e5e865e1e44" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "8aee88187ec429dc9d821408bc3565bf", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 16657, "upload_time": "2018-06-24T13:36:26", "url": "https://files.pythonhosted.org/packages/c8/3a/761d8fef2ac48f444c5ee375532713887fc18bef50bbacd3e4a06b11ebdc/sqlalchemy_json_querybuilder-1.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e5992ee0adbda46d2873da566d8f648e", "sha256": "adace07664eef76ac496318452c355fe68a97dd3dc3c6b2359656f4776df705b" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.2.1.tar.gz", "has_sig": false, "md5_digest": "e5992ee0adbda46d2873da566d8f648e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 12449, "upload_time": "2018-06-24T13:36:28", "url": "https://files.pythonhosted.org/packages/81/e9/34c596e0aad439ac616a633766515d977fc2cac1a498fd44c5061ccb1e42/sqlalchemy_json_querybuilder-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "e21bb125b29f9a857f4d0e6ac7586b4c", "sha256": "d9912c7daa79bc87653214cfc1ed89726f38f446412fa2dd63b779683d6f3563" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "e21bb125b29f9a857f4d0e6ac7586b4c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 16881, "upload_time": "2018-06-24T15:44:14", "url": "https://files.pythonhosted.org/packages/a6/c6/146d65ae3ec46eaaf52d8e244671e42ed382dcf0b927662d199ea3ca93b4/sqlalchemy_json_querybuilder-1.2.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4d729e9a0b5d092532cfdc1a512efc8f", "sha256": "c86f19175bd9616e17e6d47a921aa6d1fe043888a93fd825b57ade7b495c6bf0" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.2.2.tar.gz", "has_sig": false, "md5_digest": "4d729e9a0b5d092532cfdc1a512efc8f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 12710, "upload_time": "2018-06-24T15:44:16", "url": "https://files.pythonhosted.org/packages/6b/11/3b8b7c5e95577ad50891031ea0f1325e2268edc30e5c240505cced80c754/sqlalchemy_json_querybuilder-1.2.2.tar.gz" } ], "1.2.3": [ { "comment_text": "", "digests": { "md5": "2a4153d25cf487c68c7d976af8f9dad8", "sha256": "40906e9793530b09ff71db94c2cd302d8e0674707712fc76baaa4f273518acc3" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "2a4153d25cf487c68c7d976af8f9dad8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 16936, "upload_time": "2018-06-25T08:49:14", "url": "https://files.pythonhosted.org/packages/46/4f/499bd497ccc2d9ae5f704893c42df9488d014622a7b3444abcc5f93d7f42/sqlalchemy_json_querybuilder-1.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9b809334686bb7dcbe4ee1771839c408", "sha256": "770c99e8c81ee5b5d5e29b86730b928257a8b9273fb483bee9fc433129fac676" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.2.3.tar.gz", "has_sig": false, "md5_digest": "9b809334686bb7dcbe4ee1771839c408", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 12741, "upload_time": "2018-06-25T08:49:16", "url": "https://files.pythonhosted.org/packages/1f/cb/8cfd38dd6f4c4bea4abbf7f92f0328fccf8c16969d9ed4275c97d10dd502/sqlalchemy_json_querybuilder-1.2.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "2a4153d25cf487c68c7d976af8f9dad8", "sha256": "40906e9793530b09ff71db94c2cd302d8e0674707712fc76baaa4f273518acc3" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "2a4153d25cf487c68c7d976af8f9dad8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 16936, "upload_time": "2018-06-25T08:49:14", "url": "https://files.pythonhosted.org/packages/46/4f/499bd497ccc2d9ae5f704893c42df9488d014622a7b3444abcc5f93d7f42/sqlalchemy_json_querybuilder-1.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9b809334686bb7dcbe4ee1771839c408", "sha256": "770c99e8c81ee5b5d5e29b86730b928257a8b9273fb483bee9fc433129fac676" }, "downloads": -1, "filename": "sqlalchemy_json_querybuilder-1.2.3.tar.gz", "has_sig": false, "md5_digest": "9b809334686bb7dcbe4ee1771839c408", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 12741, "upload_time": "2018-06-25T08:49:16", "url": "https://files.pythonhosted.org/packages/1f/cb/8cfd38dd6f4c4bea4abbf7f92f0328fccf8c16969d9ed4275c97d10dd502/sqlalchemy_json_querybuilder-1.2.3.tar.gz" } ] }