2010-03-10 28 views
14

Tôi đang cố gắng tham gia cùng một bảng trong sqlalchemy. Đây là một phiên bản minimial về những gì tôi đã cố gắng:Cách tham gia cùng một bảng trong sqlalchemy

#!/usr/bin/env python 
import sqlalchemy as sa 
from sqlalchemy import create_engine 
from sqlalchemy.orm import mapper, sessionmaker, aliased 

engine = create_engine('sqlite:///:memory:', echo=True) 

metadata = sa.MetaData() 
device_table = sa.Table("device", metadata, 
    sa.Column("device_id", sa.Integer, primary_key=True), 
    sa.Column("name", sa.String(255), nullable=False), 
    sa.Column("parent_device_id", sa.Integer, sa.ForeignKey('device.device_id')), 
    ) 

class Device(object): 
    device_id = None 
    def __init__(self, name, parent_device_id=None): 
     self.name = name 
     self.parent_device_id = parent_device_id 

    def __repr__(self): 
     return "<Device(%s, '%s', %s)>" % (self.device_id, 
              self.name, 
              self.parent_device_id) 

mapper(Device, device_table) 

metadata.create_all(engine) 

db_session = sessionmaker(bind=engine)() 

parent = Device('parent') 
db_session.add(parent) 
db_session.commit() 

child = Device('child', parent.device_id) 
db_session.add(child) 
db_session.commit() 

ParentDevice = aliased(Device, name='parent_device') 
q = db_session.query(Device, ParentDevice)\ 
    .outerjoin(ParentDevice, 
       Device.parent_device_id==ParentDevice.device_id) 

print list(q) 

này mang lại cho tôi lỗi này:

ArgumentError: Can't determine join between 'device' and 'parent_device'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly.

Nhưng tôi xác định một onclause cho tham gia. Làm thế nào tôi nên làm điều này?

Trả lời

8

Đối query.[outer]join, bạn chỉ định như danh sách tham gia (đó là khác nhau để expression.[outer]join.) Vì vậy, tôi cần phải đặt 2 yếu tố của tham gia, bàn và onclause trong một tuple, như thế này:

q = db_session.query(Device, ParentDevice)\ 
    .outerjoin(
        (ParentDevice, Device.parent_device_id==ParentDevice.device_id) 
      ) 
3

Trình ánh xạ của bạn nên cụ thể hóa kết nối giữa hai mục, dưới đây là ví dụ: adjacency list relationships.

+0

Tôi không thể làm điều này để làm việc cho ví dụ trên, nhưng cảm ơn cho con trỏ đến tài liệu đó. Nó giới thiệu cho tôi một số phần của sqlalchemy mà tôi đã không nhận thức được, mà sẽ hữu ích cho tôi trong các phần khác của ứng dụng của tôi. –

+0

Để tham khảo sau này ... [liên kết này] (http://www.sqlalchemy.org/docs/orm/relationships.html#adjacency-list-relationships) là hiện tại hơn và có một ví dụ với khai báo. – Russ

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