{ "info": { "author": "JL Peyret", "author_email": "jpeyret@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "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 :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Database :: Front-Ends", "Topic :: Utilities" ], "description": "Use Python with or without an ORM.\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nPyNoORM consists of several very loosely-coupled classes that facilitate the use of Python in a web or SQL\ncontext without having to rely on an ORM. Working with an ORM is entirely possible, in fact, it's used with\nthe Django ORM and SQLAlchemy in an application that interfaces with Oracle, Microsoft SQL Server and PostgreSQL all at the same time.\n\nFocus is on:\n\n - simplicity for the user\n - support for databases that are not under \"controlled\" by the Python application or may be read-only for it.\n - performance\n\n+------------------------+-----------------------------------------------------------------------+\n| Class | Role |\n+========================+=======================================================================+\n| Binder | abstract SQL query binding |\n+------------------------+-----------------------------------------------------------------------+\n| Linker | join objects together |\n+------------------------+-----------------------------------------------------------------------+\n| TemplateGenerator | generate Django Templates dynamically from query results, loosely |\n| *(to be added)* | inspired by Django Tables 2 |\n+------------------------+-----------------------------------------------------------------------+\n\n\nThe Binder class\n================\n\nA Binder support easier raw SQL by abstracting differences in the underlying database's bind variable syntax and also substituting bind variables from a list of arguments, using dict, then attribute lookup.\n\nUsing native database binds also helps to protect you against SQL injection attacks.\n\nsupported: PostgreSQL, sqlite3, Oracle, MySQL, SQL Server\n\nBasic Use\n---------\n\nSimple **sqlite3** example::\n\n from pynoorm.binder import Binder\n binder = Binder.factory(\"qmark\")\n\n query, parameters = binder(\"select * from orders where custid = %(custid)s\", dict(custid=\"ACME\"), binder)\n\n``query`` and ``parameters`` are now in the sqlite3/qmark format::\n\n\t>>> print(query)\n\tselect * from orders where custid = ?\n\t>>> print(parameters)\n\t('ACME',)\n\nOracle, with multiple parameters ::\n\n import cx_Oracle\n binder_ora = Binder.factory(cx_Oracle.paramstyle)\n\n #just for test... assign a custid for attribute lookup\n binder_ora.custid = \"AMAZON\"\n\n tqry = \"select * from orders where custid = %(custid)s and has_shipped = %(shipped)s\"\n query, parameters = binder_ora(tqry, binder_ora, dict(custid=\"ACME\", shipped=1))\n\n >>> print(query)\n select * from orders where custid = :custid and has_shipped = :shipped\n >>> print(parameters)\n {'shipped': 1, 'custid': 'AMAZON'}\n\nSQL IN list criteria:\n\nThis allows binding of Python lists as standard SQL ``in ('foo','bar')`` expressions, but as a prepared statement.\n\nIt relies on using `'l'`, rather than `'s'` as the format qualifier. Notice the `%(custid)l` below ::\n\n from pynoorm.binder import Binder\n binder = Binder.factory(\"qmark\")\n\n query, parameters = binder(\n \"select * from orders where custid in (%(custid)l)\"\n , dict(custid=[\"ACME\",\"FOO\",\"BAR\"])\n )\n\n\nContents of `query` and `parameters`::\n \n select * from orders where custid in (?, ?, ?)\n ('ACME', 'FOO', 'BAR')\n \n\nAnd now with an empty list::\n\n query, parameters = binder(\n \"\"\"select * \n from orders \n where custid in (%(custid)l) \n and status=%(status)s\"\"\"\n , dict(custid=[], status=\"any\")\n )\n\nContents of `query` and `parameters`::\n\n\n select * from orders where custid in (NULL) and status=?\n ('any',)\n\n\n\nFeatures\n--------\n\n* adjust query to support database parameter style\n* find and prepare bind parameters from `*args`.\n\n\n\nThe Linker class\n================\n\nA Linker allows you to join objects or dictionaries without the need for an ORM. You can think of it as performing `parent-child` linking, but it uses `left-right` instead as a more neutral terminology instead.\n\nBasic use \n---------\n\nSample data, in dictionaries: ::\n\n customers = [\n dict(id=1, xref=1),\n dict(id=2, xref=2),\n ]\n\n orders = [\n dict(custid=1, xref=1, orderid=11),\n dict(custid=1, xref=1, orderid=12),\n dict(custid=2, xref=2, orderid=21),\n dict(custid=2, xref=2, orderid=22),\n ]\n\nCreate a linker, then a lookup dictionary for the left side. Finally, link the left and right side. ::\n\n linker = Linker(key_left=\"id\")\n lookup = linker.dict_from_list(customers)\n linker.link(lookup, orders, attrname_on_left=\"orders\", key_right=\"custid\")\n\n\nThe customers now have an `orders` list: ::\n\n [ { 'id': 1,\n 'orders': [ { 'custid': 1, 'orderid': 11, 'xref': 1},\n { 'custid': 1, 'orderid': 12, 'xref': 1}],\n 'xref': 1},\n { 'id': 2,\n 'orders': [ { 'custid': 2, 'orderid': 21, 'xref': 2},\n { 'custid': 2, 'orderid': 22, 'xref': 2}],\n 'xref': 2}]\n\nFeatures\n--------\n \n * supports objects or dictionaries\n * takes basic Python objects so can join across different databases, allowing for example tagging of objects in a read-only database\n * allows compound field keys and aliasing\n * orphans, on the left or the right, can be initialized with empty attribute values.\n\n\nNote on Python 3.7 support:\n---------------------------\n\n3.7 tests run to success locally, but travis-ci does not support Python 3.7 yet. So expect `builds` to show\n\"failing\" 3.7, pending resolution of Travisissue485_.\n\n.. _Travisissue485: https://github.com/jopohl/urh/pull/485\n\n\nCredits\n---------\n\nThis package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage\n\n\n=======\nHistory\n=======\n\n0.1.0 (2016-02-17)\n------------------\n\n* First release on github.\n\n0.1.1 (2016-02-22)\n------------------\n\n* Registered on PyPI\n\n0.2.0 (2016-04-12)\n------------------\n\n* Added support for Python 3.3+ and MySQL\n\n0.3.0 (2017-09-06)\n------------------\n\n* Added SQL Server support\n* Added Linker class to support object cross-referencing\n\n0.4.0 (2018-07-24)\n------------------\n\n* Updating to Beta status\n* Optimized Linker class\n* Python list => SQL IN (xxx, yyy) functionality on Binder.\n\n0.4.1 (2018-08-07)\n------------------\n\n* adjusted for Python 3 \n\n0.4.2 (2019-01-10)\n------------------\n\n* ran Black for code formatting\n* updated PyYaml to 4.2b4 to fix security vulnerability\n\n\n0.4.3 (2019-01-10)\n------------------\n\n* removed Python 3.7 from tox since that Python version is not supported yet by tox.\n\n\n0.4.4 (2019-01-15)\n------------------\n\n* adjusted list binding variable names from `__xxx_000` to `xxx_000__` because leading underscore are invalid under Oracle.\n \n1.0.2 (2019-07-15)\n------------------\n\n* Docs: added the D3.js Tree Linker example.\n* Code is stable and hasn't needed fixes or API changes despite significant use cases.", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/jpeyret/pynoorm", "keywords": "sql database multiplatform", "license": "MIT License", "maintainer": "", "maintainer_email": "", "name": "pynoorm", "package_url": "https://pypi.org/project/pynoorm/", "platform": "", "project_url": "https://pypi.org/project/pynoorm/", "project_urls": { "Homepage": "https://github.com/jpeyret/pynoorm" }, "release_url": "https://pypi.org/project/pynoorm/1.0.2/", "requires_dist": null, "requires_python": "", "summary": "Use Python with or without an ORM.", "version": "1.0.2" }, "last_serial": 5544130, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "b869e99cdc2307a4f8529eafea917e34", "sha256": "f02e7fb458de4a51303f1ed976b4a7a8f4f5226eb08bbf83e5b5d42043f50e5b" }, "downloads": -1, "filename": "pynoorm-0.1.1.macosx-10.9-x86_64.tar.gz", "has_sig": false, "md5_digest": "b869e99cdc2307a4f8529eafea917e34", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5968, "upload_time": "2016-02-23T04:35:21", "url": "https://files.pythonhosted.org/packages/81/01/8f8b31d62158c3b3f4cff8c181631d4e236097358b62792930981ba1b6e8/pynoorm-0.1.1.macosx-10.9-x86_64.tar.gz" }, { "comment_text": "", "digests": { "md5": "cfdfb3287e53b0460e8b1c65fbcfc320", "sha256": "918b1cd1605a9d162e85f6df4a8ca3e765eb6f8bffe53133f5f89b137bf52574" }, "downloads": -1, "filename": "pynoorm-0.1.1.tar.gz", "has_sig": false, "md5_digest": "cfdfb3287e53b0460e8b1c65fbcfc320", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18617, "upload_time": "2016-02-23T04:35:27", "url": "https://files.pythonhosted.org/packages/a7/d9/847cdeb6bfe2bdab983c41858450efd8ce1038d39e9bc37e479ab52be09c/pynoorm-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "4f1b701bd2bbb91d40be420e043e9248", "sha256": "771d15e0c0ecfd82bfbb0e8865a0b84f3defd15f967a571304432c4359193e55" }, "downloads": -1, "filename": "pynoorm-0.2.0.tar.gz", "has_sig": false, "md5_digest": "4f1b701bd2bbb91d40be420e043e9248", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19146, "upload_time": "2016-04-13T00:47:27", "url": "https://files.pythonhosted.org/packages/9b/87/f24a8c37f35b41c2a8b3bfd96422c36f9d75a7ea10b1bead60cbbdafe798/pynoorm-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "fd0df032e496a00d8dea3f4b6902639c", "sha256": "cb8216b2da88609ec754ea512fc7cb58cf21a9e57ca44162ba220f65e629824f" }, "downloads": -1, "filename": "pynoorm-0.3.0.tar.gz", "has_sig": false, "md5_digest": "fd0df032e496a00d8dea3f4b6902639c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 38211, "upload_time": "2017-09-07T06:04:05", "url": "https://files.pythonhosted.org/packages/fc/ad/a4840f0664eb3ab32eb4e7cf3911ce617758d547f614cdc8d380aba0031c/pynoorm-0.3.0.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "32958ba4f5eaa58fdb45101907caa1ca", "sha256": "5985d7e6a2c641a4719b22905c131dcf16acbb7015c2964e07c9550be2d3c581" }, "downloads": -1, "filename": "pynoorm-0.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "32958ba4f5eaa58fdb45101907caa1ca", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 13422, "upload_time": "2018-07-24T21:15:39", "url": "https://files.pythonhosted.org/packages/4a/e9/5b5052f21746d3f850a352d0d40bc99d983b3ce1814a39db54f699d3697a/pynoorm-0.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c73149718135a548bb3434bf753f8922", "sha256": "d0b9f5e2489aa046116f5102532ba19bab8e2a9cdabb321a19488efd70a46601" }, "downloads": -1, "filename": "pynoorm-0.4.0-py3.6.egg", "has_sig": false, "md5_digest": "c73149718135a548bb3434bf753f8922", "packagetype": "bdist_egg", "python_version": "3.6", "requires_python": null, "size": 27996, "upload_time": "2019-01-11T04:20:25", "url": "https://files.pythonhosted.org/packages/c4/9d/37f82f5f6239d0d04221c50950849402259a1e55d9d857b609f2a88db1dd/pynoorm-0.4.0-py3.6.egg" }, { "comment_text": "", "digests": { "md5": "cc69444e9115bb441ad5b47015878d69", "sha256": "45a10bc0b5fc88c837a65bb195de39045c65db60e4d39083e910edca0c9f8134" }, "downloads": -1, "filename": "pynoorm-0.4.0.tar.gz", "has_sig": false, "md5_digest": "cc69444e9115bb441ad5b47015878d69", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28804, "upload_time": "2018-07-24T21:15:41", "url": "https://files.pythonhosted.org/packages/82/96/b7e098a825d77867c414cc17e25df77537d57ea6e60ed0215b235a079bd0/pynoorm-0.4.0.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "0aed9c29a8784c5791cfc9c198fb5104", "sha256": "e9fa756913c052408b764278c6de0093472998fadbf697f95611ed7b13d44fc2" }, "downloads": -1, "filename": "pynoorm-0.4.2.tar.gz", "has_sig": false, "md5_digest": "0aed9c29a8784c5791cfc9c198fb5104", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29258, "upload_time": "2019-01-11T04:30:24", "url": "https://files.pythonhosted.org/packages/b4/3c/d02a548176965c521f2e8e8e41b80ee86d88db17d568989981a5fd414f27/pynoorm-0.4.2.tar.gz" } ], "0.4.3": [ { "comment_text": "", "digests": { "md5": "7ad2959362b984c4a84fa9d4145e673f", "sha256": "2fe76d0f6141041408c5b363b7fecc9ffe58ab0b7201ac3d57d39e524eb6e411" }, "downloads": -1, "filename": "pynoorm-0.4.3.tar.gz", "has_sig": false, "md5_digest": "7ad2959362b984c4a84fa9d4145e673f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29254, "upload_time": "2019-01-11T04:50:26", "url": "https://files.pythonhosted.org/packages/5e/95/3063613a2b255104b8ef062d390bf5e7e6a7262d90cec033b140028d24d8/pynoorm-0.4.3.tar.gz" } ], "0.4.4": [ { "comment_text": "", "digests": { "md5": "7477182839c8c951391d740882f87af1", "sha256": "a2544ad9ba3ba4375405bea371f734125eeb92561d0445fc3466f1a8d43b12cf" }, "downloads": -1, "filename": "pynoorm-0.4.4-py3.6.egg", "has_sig": false, "md5_digest": "7477182839c8c951391d740882f87af1", "packagetype": "bdist_egg", "python_version": "3.6", "requires_python": null, "size": 28241, "upload_time": "2019-07-17T04:50:11", "url": "https://files.pythonhosted.org/packages/e7/84/44d37c391781d7132ae0ba0dd97e5136fcfc130b0a00f1c140a0a93a4b51/pynoorm-0.4.4-py3.6.egg" }, { "comment_text": "", "digests": { "md5": "b932e5ae230e22b82af6b501eadcb38c", "sha256": "1b72f41a3b4fd1bb6595a8348b63567261c5c3247e30f41aff7ed909cd0fb212" }, "downloads": -1, "filename": "pynoorm-0.4.4.tar.gz", "has_sig": false, "md5_digest": "b932e5ae230e22b82af6b501eadcb38c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29455, "upload_time": "2019-01-16T05:21:18", "url": "https://files.pythonhosted.org/packages/62/00/9bce31538e84f5ad5e26b1cbbc9c29deccc4aa799df19d8ff13ac18ac28d/pynoorm-0.4.4.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "f5d52d879c72b6cfe9684a1fae87d415", "sha256": "2a96d57f395dcbaad7cb54a5ba604f17cfad377b5bf4aa2e3df08b271164bfe2" }, "downloads": -1, "filename": "pynoorm-1.0.0.tar.gz", "has_sig": false, "md5_digest": "f5d52d879c72b6cfe9684a1fae87d415", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30201, "upload_time": "2019-07-17T04:50:13", "url": "https://files.pythonhosted.org/packages/23/a5/c9e56218017ade508d72fe55cd8a7edcf33d1bb9c183e150014b799ed5bb/pynoorm-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "30af38a1eb710bb1bfa41a3152e7cc83", "sha256": "40b27f93ef8b180ce8374664ffc6e44337f0e5cd9f218b126565d8bf88a0232f" }, "downloads": -1, "filename": "pynoorm-1.0.1.tar.gz", "has_sig": false, "md5_digest": "30af38a1eb710bb1bfa41a3152e7cc83", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30202, "upload_time": "2019-07-17T04:54:59", "url": "https://files.pythonhosted.org/packages/45/ff/6888a893a3a1dd693ea2a4b62cc74755665b7172e97a522cbad902de8fbd/pynoorm-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "dfcb64b36395d750d26089bac7b22f3a", "sha256": "decfc78977aacf26c00c09ce436f9d5be7150b17bbfdf650823ed24451287e49" }, "downloads": -1, "filename": "pynoorm-1.0.2.tar.gz", "has_sig": false, "md5_digest": "dfcb64b36395d750d26089bac7b22f3a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30272, "upload_time": "2019-07-17T05:00:32", "url": "https://files.pythonhosted.org/packages/09/74/8da324b852519091b9143ab57590bc2e92cfbc51ff729c71b96a64f57747/pynoorm-1.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "dfcb64b36395d750d26089bac7b22f3a", "sha256": "decfc78977aacf26c00c09ce436f9d5be7150b17bbfdf650823ed24451287e49" }, "downloads": -1, "filename": "pynoorm-1.0.2.tar.gz", "has_sig": false, "md5_digest": "dfcb64b36395d750d26089bac7b22f3a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30272, "upload_time": "2019-07-17T05:00:32", "url": "https://files.pythonhosted.org/packages/09/74/8da324b852519091b9143ab57590bc2e92cfbc51ff729c71b96a64f57747/pynoorm-1.0.2.tar.gz" } ] }