2011-07-21 43 views
7

Về cơ bản, tôi có mô hình này, nơi tôi ánh xạ trong một bảng duy nhất là lớp "BaseNode" và hai lớp con. Vấn đề là tôi cần một trong các lớp con, để có mối quan hệ một-nhiều với lớp con khác. Vì vậy, trong sắp xếp, nó là một mối quan hệ với một hàng của lớp khác nhau (phân lớp), nhưng trong cùng một bảng. Làm thế nào để bạn nghĩ rằng tôi có thể viết nó bằng cách sử dụng cú pháp khai báo ?.SQLAlchemy Mối quan hệ một-nhiều đối với thừa kế bảng đơn - khai báo

Lưu ý: Do các mối quan hệ khác trong mô hình của tôi, nếu có thể, tôi thực sự cần phải gắn bó với kế thừa bảng đơn.

class BaseNode(DBBase): 
    __tablename__ = 'base_node' 
    id = Column(Integer, primary_key=True) 
    discriminator = Column('type', String(50)) 
    __mapper_args__ = {'polymorphic_on': discriminator} 

class NodeTypeA(BaseNode): 
    __mapper_args__ = {'polymorphic_identity': 'NodeTypeA'} 
    typeB_children = relationship('NodeTypeB', backref='parent_node') 


class NodeTypeB(BaseNode): 
    __mapper_args__ = {'polymorphic_identity': 'NodeTypeB'} 
    parent_id = Column(Integer, ForeignKey('base_node.id')) 

Sử dụng mã này sẽ ném:

sqlalchemy.exc.ArgumentError: NodeTypeA.typeB_children and back-reference NodeTypeB.parent_node are both of the same direction . Did you mean to set remote_side on the many-to-one side ?

Bất kỳ ý tưởng hoặc đề nghị?

Trả lời

8

Tôi đã đấu tranh thông qua bản thân mình trước đó. Tôi đã có thể để có được tự tham chiếu này mối quan hệ làm việc:

class Employee(Base): 
    __tablename__ = 'employee' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(64), nullable=False) 
Employee.manager_id = Column(Integer, ForeignKey(Employee.id)) 
Employee.manager = relationship(Employee, backref='subordinates', 
    remote_side=Employee.id) 

Lưu ý rằng managermanager_id là "khỉ vá" bởi vì bạn không thể làm cho tự tài liệu tham khảo trong một định nghĩa lớp.

Vì vậy, trong ví dụ của bạn, tôi sẽ đoán đây:

class NodeTypeA(BaseNode): 
    __mapper_args__ = {'polymorphic_identity': 'NodeTypeA'} 
    typeB_children = relationship('NodeTypeB', backref='parent_node', 
     remote_side='NodeTypeB.parent_id') 

EDIT: Về cơ bản những gì lỗi của bạn là nói cho bạn là các mối quan hệ và backref của nó đều giống hệt nhau. Vì vậy, bất kỳ quy tắc nào SA đang áp dụng để tìm ra mối quan hệ cấp bảng là gì, chúng không thích thú với thông tin bạn đang cung cấp.

Tôi đã học được rằng chỉ cần nói mycolumn=relationship(OtherTable) trong lớp khai báo của bạn sẽ dẫn đến việc mycolumn là một danh sách, giả sử SA có thể phát hiện một mối quan hệ rõ ràng. Vì vậy, nếu bạn thực sự muốn một đối tượng có một liên kết đến cha mẹ của nó, chứ không phải là con của nó, bạn có thể xác định parent=relationship(OtherTable, backref='children', remote_side=OtherTable.id) trong bảng con. Điều đó định nghĩa cả hai hướng của mối quan hệ cha-con.

+0

Cảm ơn bạn đã trả lời nhanh chóng !. Tôi đã thử, nhưng tôi vẫn gặp lỗi tương tự. Tôi nên thay đổi lớp NodeTypeB như thế nào ?. Trong mã của bạn, bạn xác định Employee.manager_id và Employee.manager bên ngoài định nghĩa lớp. Nhưng trong đề xuất của bạn cho mã của tôi, bạn đã không. Xin lỗi tôi nghĩ rằng tôi không hiểu rõ. Trân trọng. –

+0

Các tài liệu SQLAlchemy nói rằng nó là OK để cung cấp các chuỗi mà có được eval'd để bạn có thể nhận được xung quanh lỗi cú pháp tự tham khảo. Nhưng tôi chưa bao giờ thử nó. – wberry

+0

Trong NodeTypeB, khóa ngoại của bạn là asset_base. Tôi đoán đó là lỗi đánh máy hoặc bạn quên thay đổi tên trước khi đăng. Tôi nghĩ rằng nếu bạn thay đổi ForeignKey ('asset_base.id') sang ForeignKey (NodeTypeA.id) thì nó sẽ gần với ví dụ làm việc của tôi. – wberry

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