Library for implementing Modified Preorder Tree Traversal with your SQLAlchemy Models and working with trees of Model instances, like django-mptt. Docs http://sqlalchemy-mptt.readthedocs.io/
The nested set model is a particular technique for representing nested sets (also known as trees or hierarchies) in relational databases.
Installing
Install from github:
pip install git+http://github.com/uralbash/sqlalchemy_mptt.git
PyPi:
pip install sqlalchemy_mptt
Source:
pip install -e .
Usage
Add mixin to model
from sqlalchemy import Column, Integer, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy_mptt.mixins import BaseNestedSets
Base = declarative_base()
class Tree(Base, BaseNestedSets):
__tablename__ = "tree"
id = Column(Integer, primary_key=True)
visible = Column(Boolean)
def __repr__(self):
return "<Node (%s)>" % self.id
Now you can add, move and delete obj!
Insert node
node = Tree(parent_id=6)
session.add(node)
level Nested sets example
1 1(1)22
_______________|___________________
| | |
2 2(2)5 6(4)11 12(7)21
| ^ ^
3 3(3)4 7(5)8 9(6)10 13(8)16 17(10)20
| |
4 14(9)15 18(11)19
level Insert node with parent_id == 6
1 1(1)24
_______________|_________________
| | |
2 2(2)5 6(4)13 14(7)23
| ____|____ ___|____
| | | | |
3 3(3)4 7(5)8 9(6)12 15(8)18 19(10)22
| | |
4 10(23)11 16(9)17 20(11)21
Delete node
node = session.query(Tree).filter(Tree.id == 4).one()
session.delete(node)
level Nested sets example
1 1(1)22
_______________|___________________
| | |
2 2(2)5 6(4)11 12(7)21
| ^ ^
3 3(3)4 7(5)8 9(6)10 13(8)16 17(10)20
| |
4 14(9)15 18(11)19
level Delete node == 4
1 1(1)16
_______________|_____
| |
2 2(2)5 6(7)15
| ^
3 3(3)4 7(8)10 11(10)14
| |
4 8(9)9 12(11)13
Update node
node = session.query(Tree).filter(Tree.id == 8).one()
node.parent_id = 5
session.add(node)
level Nested sets example
1 1(1)22
_______________|___________________
| | |
2 2(2)5 6(4)11 12(7)21
| ^ ^
3 3(3)4 7(5)8 9(6)10 13(8)16 17(10)20
| |
4 14(9)15 18(11)19
level Move 8 - > 5
1 1(1)22
_______________|__________________
| | |
2 2(2)5 6(4)15 16(7)21
| ^ |
3 3(3)4 7(5)12 13(6)14 17(10)20
| |
4 8(8)11 18(11)19
|
5 9(9)10
Move node (support multitree)
Nested sets multitree
Move inside
node = session.query(Tree).filter(Tree.id == 4).one()
node.move_inside("15")
4 -> 15
level Nested sets tree1
1 1(1)16
_______________|_____________________
| |
2 2(2)5 6(7)15
| ^
3 3(3)4 7(8)10 11(10)14
| |
4 8(9)9 12(11)13
level Nested sets tree2
1 1(12)28
________________|_______________________
| | |
2 2(13)5 6(15)17 18(18)27
| ^ ^
3 3(14)4 7(4)12 13(16)14 15(17)16 19(19)22 23(21)26
^ | |
4 8(5)9 10(6)11 20(20)21 24(22)25
Move after
node = session.query(Tree).filter(Tree.id == 8).one()
node.move_after("5")
level Nested sets example
1 1(1)22
_______________|___________________
| | |
2 2(2)5 6(4)11 12(7)21
| ^ ^
3 3(3)4 7(5)8 9(6)10 13(8)16 17(10)20
| |
4 14(9)15 18(11)19
level Move 8 after 5
1 1(1)22
_______________|__________________
| | |
2 2(2)5 6(4)15 16(7)21
| ^ |
3 3(3)4 7(5)8 9(8)12 13(6)14 17(10)20
| |
4 10(9)11 18(11)19
Move to top level
node = session.query(Tree).filter(Tree.id == 15).one()
node.move_after("1")
level tree_id = 1
1 1(1)22
_______________|___________________
| | |
2 2(2)5 6(4)11 12(7)21
| ^ ^
3 3(3)4 7(5)8 9(6)10 13(8)16 17(10)20
| |
4 14(9)15 18(11)19
level tree_id = 2
1 1(15)6
^
2 2(16)3 4(17)5
level tree_id = 3
1 1(12)16
_______________|
| |
2 2(13)5 6(18)15
| ^
3 3(14)4 7(19)10 11(21)14
| |
4 8(20)9 12(22)13
Support and Development
To report bugs, use the issue tracker.
We welcome any contribution: suggestions, ideas, commits with new futures, bug fixes, refactoring, docs, tests, translations, etc…
If you have any questions:
Use the Discussion board
Contact the maintainer via email: fayaz.yusuf.khan@gmail.com
Contact the author via email: sacrud@uralbash.ru or #sacrud IRC channel
Refer the detailed contribution guide in the docs for more information on setting up the development environment, running tests, and contributing to the project.
License
The project is licensed under the MIT license.
Versions releases 0.2.x & above
0.6.0 (2025-11-29)
see issues #109, #111, #112 & #113
Add support for SQLAlchemy 2.0.
Add official support for Python 3.12, 3.13 and 3.14.
Remove examples of defunct features from the documentation.
0.5.0 (2025-11-18)
see issues #104 & #110
Add support for SQLAlchemy 1.4.
Drop official support for PyPy.
Simplify memory management by using weakref.WeakSet instead of rolling our own weak reference set.
Unify after_flush_postexec execution path for CPython & PyPy.
Simplify get_siblings.
Run doctest on all code snippets in the documentation.
Fix some of the incorrect documentation snippets.
0.4.0 (2025-05-30)
see issue #97
Support for Python 3.10 and 3.11
Dropped support for Python 3.7
0.3.0 (2025-05-10)
see issues #63, #87, #89 & #90
Support for joined-table inheritance
Restrict to Python & PyPy 3.7 - 3.9
Restrict to SQLA 1.0 - 1.3
Fixes race condition with garbage collection on PyPy versions
0.2.5 (2019-07-23)
see issue #64
Added similar django_mptt methods get_siblings and get_children
0.2.4 (2018-12-14)
see PR #61
Allow to specify ordering of path_to_root
0.2.3 (2018-06-03)
see issue #57
Fix rebuild tree
Added support node’s identifier start from 0
0.2.2 (2017-10-05)
see issue #56
Added custom default root level. Support Django style level=0
0.2.1 (2016-01-23)
see PR #51
fix of index columns names
0.2.0 (2015-11-13)
see PR #50
Changed parent_id to dynamically match the type of the primary_key
exposed drilldown_tree’s logic and path_to_root’s logic as both instance and class level method
Release files for sqlalchemy-mptt 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sqlalchemy_mptt-0.6.0.tar.gz | 16.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sqlalchemy_mptt-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.5 kB
Release files / sqlalchemy_mptt-0.6.0.tar.gz
| Download URL | sqlalchemy_mptt-0.6.0.tar.gz |
|---|---|
| Size | 16.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8e955daca8ac90ea2d6186943bed093082dfc143366de8abbee6c305fd2bcaa4
|
|
BLAKE2b-256 checksum How to use checksums |
6e9cea743d7ebe776f65bd77b3ec303eafdd80f2acd989aa2660598ed57394b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 30, 2025.
Transparency logRelease files / sqlalchemy_mptt-0.6.0-py3-none-any.whl
| Download URL | sqlalchemy_mptt-0.6.0-py3-none-any.whl |
|---|---|
| Size | 14.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3947ba7edaf5b82e578c681d971f79efa7dce04672cdb30f108b7bc1743e8af0
|
|
BLAKE2b-256 checksum How to use checksums |
937d0a774dfb62a09225fe4ac174a0a67111f07e29e131dcad61af87d2704b2b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 30, 2025.
Transparency log