{ "info": { "author": "saaj", "author_email": "mail@saaj.me", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "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 :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Database", "Topic :: Software Development :: Libraries" ], "description": ".. image:: https://bitbucket-badges.atlassian.io/badge/saaj/fangorn.svg?ref=default\n :target: https://bitbucket.org/saaj/fangorn/addon/pipelines/home\n.. image:: https://codecov.io/bitbucket/saaj/fangorn/branch/default/graph/badge.svg\n :target: https://codecov.io/bitbucket/saaj/fangorn/branch/default\n.. image:: https://badge.fury.io/py/Fangorn.png\n :target: https://pypi.python.org/pypi/Fangorn\n\n*******\nFangorn\n*******\n\nNested Sets aka Modified Pre-order Tree Traversal (MPTT) *SQL* tree implemented in Python\nfor *MySQL* and *SQLite*. Uses both traversal markup (left, right) and adjacency list\nparentId for more ad-hoc query flexibility.\n\nProvides tree structure validation and \"memorisation\" via SQLite *:memory:* for quick reads.\n\nExample\n=======\n\nWe want to achieve the following tree. Node is represented by ``name id \u2192 parentId (l, r)``.\nTo output a tree this way ``fangorn.test.visualize`` function can be used.\n\n.. sourcecode:: text\n\n R 1 \u2192 None (1, 18)\n \u2514\u2500A1 2 \u2192 1 (2, 5)\n \u2514\u2500B1 3 \u2192 2 (3, 4)\n \u2514\u2500A2 4 \u2192 1 (6, 13)\n \u2514\u2500B2 5 \u2192 4 (7, 8)\n \u2514\u2500B3 6 \u2192 4 (9, 12)\n \u2514\u2500C1 7 \u2192 6 (10, 11)\n \u2514\u2500A3 8 \u2192 1 (14, 17)\n \u2514\u2500B4 9 \u2192 8 (15, 16)\n\nFirst we need a table to represent the tree. And we want a tree node to have a name.\n\n.. sourcecode:: python\n\n import MySQLdb as mysql\n conn = mysql.connect(user = 'guest', db = 'test')\n conn.query('''\n CREATE TABLE `node` (\n `node_id` int(10) unsigned NOT NULL AUTO_INCREMENT,\n `parent_id` int(10) unsigned DEFAULT NULL,\n `l` int(10) unsigned NOT NULL,\n `r` int(10) unsigned NOT NULL,\n `name` varchar(8) NOT NULL,\n PRIMARY KEY (`node_id`),\n KEY `l` (`l`),\n KEY `r` (`r`),\n KEY `parent_id` (`parent_id`),\n CONSTRAINT `node_has_node` FOREIGN KEY (`parent_id`)\n REFERENCES `node` (`node_id`)\n ON DELETE CASCADE\n ON UPDATE CASCADE\n ) ENGINE=InnoDB;\n ''')\n\nNow we can create tree instance. Note that DAO that the tree relies on is expected to support\n*named* DB-API paramstyle (i.e. `WHERE node_id = :nodeId`). Also transaction control methods\nare recommended to implement nested transaction support. However test suite requires nested\ntransactions to run. For `MySQLdb` and `sqlite3` there're compatibility wrappers under\n`fangorn.compat`.\n\n.. sourcecode:: python\n\n import fangorn\n from fangorn.compat.mysqldb import Mysqldb as MysqldbWrapper\n tree = fangorn.NestedSetsTree(MysqldbWrapper(conn), 'node', ('name',))\n\n rId = tree.add(dict(name = 'R'))\n a1Id = tree.add(dict(name = 'A1'), parentId = rId)\n tree.add(dict(name = 'B1'), parentId = a1Id)\n a2Id = tree.add(dict(name = 'A2'), parentId = rId)\n b2Id = tree.add(dict(name = 'B2'), parentId = a2Id)\n b3Id = tree.add(dict(name = 'B3'), prevId = b2Id)\n tree.add(dict(name = 'C1'), parentId = b3Id)\n a3Id = tree.add(dict(name = 'A3'), parentId = rId)\n tree.add(dict(name = 'B4'), parentId = a3Id)\n\n tree.move(a1Id, rId)\n tree.move(a3Id, prevId = a2Id)\n\nNow we can play with the tree.\n\n.. sourcecode:: python\n\n print(tree.isDescendantOf(a2Id, 4)) # False\n print(tree.isDescendantOf(a2Id, 6)) # True\n print(tree.isDescendantOf(a2Id, 7)) # True\n print(tree.isDescendantOf(a2Id, 9)) # False\n\n print([n['name'] for n in tree.getChildren(a2Id)]) # ['B2', 'B3']\n print([n['name'] for n in tree.getDescendants(a2Id)]) # ['B2', 'B3', 'C1']\n print([n['name'] for n in tree.getPath(7)]) # ['R', 'A2', 'B3', 'C1']\n\n print(tree.getNode(8)) # {'left': 14L, 'right': 17L, 'nodeId': 8L, 'name': 'A3', 'parentId': 1L}\n print(tree.getParent(8)) # {'left': 1L, 'right': 18L, 'nodeId': 1L, 'name': 'R', 'parentId': None}\n print(tree.getRoot()) # {'left': 1L, 'right': 18L, 'nodeId': 1L, 'name': 'R', 'parentId': None}\n\n tree.edit(1, dict(name = 'RR'))\n print(tree.getRoot()) # {'left': 1L, 'right': 18L, 'nodeId': 1L, 'name': 'RR', 'parentId': None}\n\n print([n['name'] for n in tree.getDescendants(a2Id)] # ['B2', 'B3', 'C1'])\n tree.remove(b3Id)\n print([n['name'] for n in tree.getDescendants(a2Id)] # ['B2'])\n\n\nFor more usage examples look at project's\n`test suite `_.\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://bitbucket.org/saaj/fangorn", "keywords": "python tree nested-sets mysql sqlite", "license": "LGPL-2.1+", "maintainer": "", "maintainer_email": "", "name": "Fangorn", "package_url": "https://pypi.org/project/Fangorn/", "platform": "Any", "project_url": "https://pypi.org/project/Fangorn/", "project_urls": { "Homepage": "https://bitbucket.org/saaj/fangorn" }, "release_url": "https://pypi.org/project/Fangorn/0.3.2/", "requires_dist": null, "requires_python": "", "summary": "Nested Sets SQL Tree for Python", "version": "0.3.2" }, "last_serial": 2653430, "releases": { "0.2.1": [ { "comment_text": "", "digests": { "md5": "f8ba2a2fa16761151833397c3d3dc832", "sha256": "e86f3c787f92ef7940daf039b6576c010aaf36e4dfc3a4a28e2f9a3f18e00d0a" }, "downloads": -1, "filename": "Fangorn-0.2.1.zip", "has_sig": false, "md5_digest": "f8ba2a2fa16761151833397c3d3dc832", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 128031, "upload_time": "2013-06-04T16:54:53", "url": "https://files.pythonhosted.org/packages/cc/d3/0b9d991aff13eeef0d72acb7e29e220536f69ea666789788a854434bca2a/Fangorn-0.2.1.zip" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "2f3acc48917ece54ef86ccc6ac8f50c9", "sha256": "56aaddfe9ad7e8f59b854ea6f9b1201b91b9ffe5ab5a02011c543b41713be30f" }, "downloads": -1, "filename": "Fangorn-0.3.0.tar.gz", "has_sig": false, "md5_digest": "2f3acc48917ece54ef86ccc6ac8f50c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 126387, "upload_time": "2015-07-04T19:21:03", "url": "https://files.pythonhosted.org/packages/f5/8d/2f9cd018b4f25a2dade8140330b0e64e3af41367d8be9db8413ceab27efb/Fangorn-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "649920e6b30a5c9e17fdfa8b0c52c7bb", "sha256": "eb327d9db357e36a3d495cc0d97a81fa3016212f2678dee364ff1f263cf078b7" }, "downloads": -1, "filename": "Fangorn-0.3.1.tar.gz", "has_sig": false, "md5_digest": "649920e6b30a5c9e17fdfa8b0c52c7bb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50537, "upload_time": "2015-07-07T07:35:56", "url": "https://files.pythonhosted.org/packages/e6/0a/fcf46a8ca08833aeb0235886b0346beaadaa564e97a873c7f17742241734/Fangorn-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "7857546112696d64ab35dd2095c1bed4", "sha256": "1fe6f17b16ed36a42885ce39f0a9aa2fe2ff14f3cb91960af6843b842e536e9e" }, "downloads": -1, "filename": "Fangorn-0.3.2.tar.gz", "has_sig": false, "md5_digest": "7857546112696d64ab35dd2095c1bed4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 52606, "upload_time": "2017-02-19T20:58:40", "url": "https://files.pythonhosted.org/packages/c2/cd/94b08418e03542cc96d706dfdb2b5307f54a200ca56c3cf975f4555cef04/Fangorn-0.3.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7857546112696d64ab35dd2095c1bed4", "sha256": "1fe6f17b16ed36a42885ce39f0a9aa2fe2ff14f3cb91960af6843b842e536e9e" }, "downloads": -1, "filename": "Fangorn-0.3.2.tar.gz", "has_sig": false, "md5_digest": "7857546112696d64ab35dd2095c1bed4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 52606, "upload_time": "2017-02-19T20:58:40", "url": "https://files.pythonhosted.org/packages/c2/cd/94b08418e03542cc96d706dfdb2b5307f54a200ca56c3cf975f4555cef04/Fangorn-0.3.2.tar.gz" } ] }