2013-02-14 36 views
9

Tôi có một bảng cha được gọi là pbx_point có cột point_type. Tôi cũng có một bảng con được gọi là pbx_route, với một cột được gọi là point_id chỉ về pbx_point.Trong sqlalchemy, làm thế nào tôi có thể sử dụng thừa kế bảng đa hình thừa kế khi bảng con có nhiều khóa nước ngoài vào bảng cha?

Tôi muốn sử dụng thừa kế bảng tham gia SQLAlchemy để liên hệ giữa hai bảng thông qua cơ sở khai báo, và sử dụng thừa kế đa hình

này hoạt động tốt - hay đúng hơn, nó sẽ, nếu không muốn nói cho các hạn chế bổ sung sau đây: pbx_point cũng có khóa ngoài gọi là initial_route_id trỏ đến pbx_route.

Tôi cũng đang sử dụng phản ánh bên dưới, nhưng db như tôi đã mô tả ở trên. Lỗi tôi nhận được là sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 'pbx_point' and 'pbx_route'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly..

Điều này có nghĩa là cơ sở delcarative "đằng sau hậu trường" đang tạo thuộc tính relationship() trên cả hai lớp được ánh xạ. Tôi muốn nó chọn pbx_route.point_id làm liên kết parent_id nhưng cũng thấy cột pbx_point.initial_route_id. Điều này sẽ đơn giản để sửa chữa, nếu tôi đã tạo ra mối quan hệ này(), nhưng tôi không - hệ thống thừa kế khai báo là.

Có một đối số bổ sung nào tôi có thể chuyển đến __mapper_args__, chẳng hạn như polymorphic_parent_col để tôi chỉ định khóa ngoại mà tôi mong muốn không? Nếu không, làm thế nào tôi có thể làm việc xung quanh vấn đề này?

Cảm ơn.

class MyBase(DeferredReflection): 
    @declared_attr 
    def __tablename__(cls): 
     return cls.__name__.lower() 

Base = declarative_base(cls=MyBase) 

class pbx_point(Base): 
    __mapper_args__ = dict(
     polymorphic_on='point_type', 
     with_polymorphic='*', 
    ) 

class pbx_route(pbx_point): 
    __mapper_args__ = dict(polymorphic_identity='pbx.route') 

Đây là stack trace Tôi nhận:

Traceback (most recent call last): 
    File "db.py", line 50, in <module> 
    Base.prepare(engine) 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", line 431, in prepare 
    thingy.map() 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 379, in map 
    **mapper_args 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/orm/__init__.py", line 1147, in mapper 
    return Mapper(class_, local_table, *args, **params) 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 213, in __init__ 
    self._configure_inheritance() 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 517, in _configure_inheritance 
    self.local_table) 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/sql/util.py", line 397, in join_condition 
    "join explicitly." % (a.description, b.description)) 
sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 'pbx_point' and 'pbx_route'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly. 

nào cho thấy nó đang hấp hối tại https://bitbucket.org/sqlalchemy/sqlalchemy/src/7f3494ebad58/lib/sqlalchemy/orm/mapper.py?at=default#cl-517. Một vài dòng ở trên làm cho tham chiếu đến trình ánh xạ kwarg inherit_condition, dường như là những gì tôi cần.

Trả lời

10

Khóa là đối số inherit_condition cho người lập bản đồ. Thông tin đa hình không thực sự có liên quan gì đến bước này.

mô hình Corrected:

class MyBase(DeferredReflection): 
    @declared_attr 
    def __tablename__(cls): 
     return cls.__name__.lower() 

Base = declarative_base(cls=MyBase) 

class pbx_point(Base): 
    __mapper_args__ = dict(
     polymorphic_on='point_type', 
     with_polymorphic='*', 
    ) 
    id = Column(Integer, primary_key=True) 

class pbx_route(pbx_point): 
    point_id = Column(Integer, ForeignKey(pbx_point.id)) 
    __mapper_args__ = dict(
     polymorphic_identity='pbx.route', 
     inherit_condition=(point_id == pbx_point.id) 
    ) 

tôi cần phải thêm các cột idpoint_id để sử dụng chúng trong đối số inherit_condition. Có khả năng là một cách để làm điều này chỉ bằng cách sử dụng sự phản chiếu, nhưng đây không phải là một trở ngại khủng khiếp.

+1

Tôi gặp vấn đề chính xác này và KHÔNG thể tìm thấy nó trong tài liệu. Cảm ơn câu trả lời. –

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