Source code for examples.adjacency_list.adjacency_list
from sqlalchemy import Column
from sqlalchemy import create_engine
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import backref
from sqlalchemy.orm import joinedload
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Session
from sqlalchemy.orm.collections import attribute_mapped_collection
Base = declarative_base()
class TreeNode(Base):
__tablename__ = "tree"
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey(id))
name = Column(String(50), nullable=False)
children = relationship(
"TreeNode",
# cascade deletions
cascade="all, delete-orphan",
# many to one + adjacency list - remote_side
# is required to reference the 'remote'
# column in the join condition.
backref=backref("parent", remote_side=id),
# children will be represented as a dictionary
# on the "name" attribute.
collection_class=attribute_mapped_collection("name"),
)
def __init__(self, name, parent=None):
self.name = name
self.parent = parent
def __repr__(self):
return "TreeNode(name=%r, id=%r, parent_id=%r)" % (
self.name,
self.id,
self.parent_id,
)
def dump(self, _indent=0):
return (
" " * _indent
+ repr(self)
+ "\n"
+ "".join([c.dump(_indent + 1) for c in self.children.values()])
)
if __name__ == "__main__":
engine = create_engine("sqlite://", echo=True)
def msg(msg, *args):
msg = msg % args
print("\n\n\n" + "-" * len(msg.split("\n")[0]))
print(msg)
print("-" * len(msg.split("\n")[0]))
msg("Creating Tree Table:")
Base.metadata.create_all(engine)
session = Session(engine)
node = TreeNode("rootnode")
TreeNode("node1", parent=node)
TreeNode("node3", parent=node)
node2 = TreeNode("node2")
TreeNode("subnode1", parent=node2)
node.children["node2"] = node2
TreeNode("subnode2", parent=node.children["node2"])
msg("Created new tree structure:\n%s", node.dump())
msg("flush + commit:")
session.add(node)
session.commit()
msg("Tree After Save:\n %s", node.dump())
TreeNode("node4", parent=node)
TreeNode("subnode3", parent=node.children["node4"])
TreeNode("subnode4", parent=node.children["node4"])
TreeNode("subsubnode1", parent=node.children["node4"].children["subnode3"])
# remove node1 from the parent, which will trigger a delete
# via the delete-orphan cascade.
del node.children["node1"]
msg("Removed node1. flush + commit:")
session.commit()
msg("Tree after save:\n %s", node.dump())
msg(
"Emptying out the session entirely, selecting tree on root, using "
"eager loading to join four levels deep."
)
session.expunge_all()
node = (
session.query(TreeNode)
.options(
joinedload("children")
.joinedload("children")
.joinedload("children")
.joinedload("children")
)
.filter(TreeNode.name == "rootnode")
.first()
)
msg("Full Tree:\n%s", node.dump())
msg("Marking root node as deleted, flush + commit:")
session.delete(node)
session.commit()
当前内容版权归 SQLAlchemy 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 SQLAlchemy .