2011-04-15 35 views
9

Tôi có một nút lớp với ánh xạ tự tham chiếu 'trẻ em' (backref 'parent') đại diện cho một cây trong SQLAlchemy và tôi muốn chọn toàn bộ cây. Nếu tôi làmXây dựng toàn bộ cây từ mối quan hệ danh sách kề kề SQLAlchemy

session.query(Node).all() 

thì mọi quyền truy cập vào node.children sẽ kích hoạt lựa chọn. Nếu tôi tham gia, hãy tải

session.query(Node).options(joinedload_all('children')).all() 

sau đó sql được cấp có một bảng không cần thiết tham gia vì tôi muốn toàn bộ cây (tất cả các nút). Có cách nào để làm điều này trong SA hay tôi chỉ nên xây dựng cây bên ngoài của riêng tôi của SA?

Trả lời

12

Không có vấn đề gì với thuộc tính gốc vì tất cả thông tin cần thiết đã được tải trong đối tượng. SQLAlchemy chỉ cần tìm đối tượng cha trong truy vấn phiên và truy vấn khi nó bị thiếu. Nhưng điều này không làm việc cho trẻ em: thư viện không thể chắc chắn tất cả các đối tượng trẻ em đã có trong phiên. Vì vậy, bạn có thể tự xây dựng cây và hướng dẫn SQLAlchemy sử dụng dữ liệu này qua set_committed_value:

from collections import defaultdict 
from sqlalchemy.orm.attributes import set_committed_value 

nodes = session.query(Node).all() 

# Collect parent-child relations 
children = defaultdict(list) 
for node in nodes: 
    if node.parent: 
     children[node.parent.id].append(node) 

# Set collected values 
for node in nodes: 
    set_committed_value(node, 'children', children[node.id]) 
+1

Tuyệt vời. Do dự của tôi với việc xây dựng cây, bản thân mình đã làm bẩn các đối tượng nút, set_committed_value là những gì tôi cần. Cảm ơn. – SquaredLoss

Các vấn đề liên quan