[PYTHON] SQLalchemy의 자체 참조 테이블에서 트리 만들기
PYTHONSQLalchemy의 자체 참조 테이블에서 트리 만들기
나는 아이폰 지향 사이트 용 플라스크에 기본 CMS를 구축하고 있으며, 약간의 문제가있다. 나는 단 하나의 테이블 (페이지)을 가진 아주 작은 데이터베이스를 가지고있다. 여기에 모델이 있습니다.
class Page(db.Model):
__tablename__ = 'pages'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
parent_id = db.Column(db.Integer, db.ForeignKey("pages.id"), nullable=True)
보시다시피 하위 페이지의 경우 parent_id 필드의 다른 페이지 객체를 참조하기 만합니다. 관리자 패널에서 수행하려는 작업은 상위 페이지에 중첩 된 모든 페이지가있는 중첩되지 않은 목록이 있습니다. 나는이 일을하는 법을 거의 모른다. 내가 생각할 수있는 것은 다음과 같다 (어쩌면 - 나는 그것을 테스트하지 않았다) 2 레벨 아래로) :
pages = Page.query.filter_by(parent_id=None)
for page in pages:
if Page.query.filter_by(parent_id=page.id):
page.sub_pages = Page.query.filter_by(parent_id=page.id)
그런 다음 템플릿의 목록으로 서식을 지정합니다. 잠재적으로 10 개가 넘는 중첩 페이지로이 작업을 어떻게 만들 수 있습니까?
미리 감사드립니다.
편집 : 조금 주위를 둘러 보았고 http://www.sqlalchemy.org/docs/orm/relationships.html#adjacency-list-relationships를 찾았습니다.
children = db.relationship("Page", backref=db.backref("parent", remote_side=id))
내 페이지 모델의 맨 아래에. 재귀 적으로 모든 것을 거쳐 오브젝트의 트리에 추가하는 것을보고 있습니다. 나는 아마 아무 의미도 만들지 못했지만 그것을 설명 할 수있는 가장 좋은 방법이다.
편집 2 : 모든 페이지를 실행하고 모든 페이지와 자녀가있는 큰 중첩 사전을 생성하는 재귀 함수를 만들었지 만 파이썬이 계속 충돌하므로 무한 루프라고 생각합니다. 기능
def get_tree(base_page, dest_dict):
dest_dict = { 'title': base_page.title, 'content': base_page.content }
children = base_page.children
if children:
dest_dict['children'] = {}
for child in children:
get_tree(base_page, dest_dict)
else:
return
그리고 내가 테스트 할 페이지 :
@app.route('/test/')
def test():
pages = Page.query.filter_by(parent_id=None)
pages_dict = {}
for page in pages:
get_tree(page, pages_dict)
return str(pages_dict)
누구 아이디어있어?
해결법
-
==============================
1.http://sqlamp.angri.ru/index.html을보십시오.
http://sqlamp.angri.ru/index.html을보십시오.
또는 http://www.sqlalchemy.org/trac/browser/examples/adjacency_list/adjacency_list.py
UPD : adjacency_list.py 선언적 예제
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base(metadata=metadata) class TreeNode(Base): __tablename__ = 'tree' id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey('tree.id')) name = Column(String(50), nullable=False) children = relationship('TreeNode', # cascade deletions cascade="all", # many to one + adjacency list - remote_side # is required to reference the 'remote' # column in the join condition. backref=backref("parent", remote_side='TreeNode.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 append(self, nodename): self.children[nodename] = TreeNode(nodename, parent=self) def __repr__(self): return "TreeNode(name=%r, id=%r, parent_id=%r)" % ( self.name, self.id, self.parent_id )
재귀 수정
def get_tree(base_page, dest_dict): dest_dict = { 'title': base_page.title, 'content': base_page.content } children = base_page.children if children: dest_dict['children'] = {} for child in children: get_tree(child, dest_dict) else: return
예제에서 쿼리를 사용하여 db의 재귀 적 페치 데이터를 얻습니다.
# 4 level deep node = session.query(TreeNode).\ options(joinedload_all("children", "children", "children", "children")).\ filter(TreeNode.name=="rootnode").\ first()
from https://stackoverflow.com/questions/4896104/creating-a-tree-from-self-referential-tables-in-sqlalchemy by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Python과 lmfit : 공유 매개 변수로 여러 데이터 세트를 맞추는 방법? (0) | 2018.11.03 |
---|---|
[PYTHON] Python 클래스를 사용하여 RDD를 처리하는 방법은 무엇입니까? (0) | 2018.11.03 |
[PYTHON] 모델 limit_choices_to = { 'user': 사용자} (0) | 2018.11.03 |
[PYTHON] 팬더 : 막대 그래프 xtick 주파수 (0) | 2018.11.03 |
[PYTHON] matplotlib를 사용하여 부드러운 선 그래프 생성 (0) | 2018.11.03 |