2011-07-21 9 views
7

基本的に、私は単一のテーブルに "BaseNode"クラスと2つのサブクラスをマップしたこのモデルを持っています。要点は、他のサブクラスと1対多の関係を持つために、サブクラスの1つが必要なことです。 ソートでは、異なるクラス(サブクラス)の別の行との関係ですが、同じ表内にあります。 宣言構文を使ってどうやって書くことができると思いますか?SQLAlchemy 1つのテーブルの継承で1対多の関係 - 宣言

注:私のモデル内の他の関係のため、可能であれば、私は本当に単一のテーブルの継承に固執する必要があります。このコードを使用して

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')) 

がスローされます。

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 ?

任意のアイデアや提案を?

答えて

8

私はこれ以前に自分自身で苦労していました。 managermanager_id「モンキー・パッチの適用」あなたはクラス定義内に自己参照を行うことができないためであることを

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) 

注:私はこの自己参照関係の作業を取得することができました。

だからあなたの例では、私はこの推測:

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

EDIT:基本的にはどのようなあなたのエラーがあなたを語っていることは関係とその後方参照の両方が同一であることです。したがって、SAがテーブルレベルの関係が何であるかを把握するために適用されているルールは、提供している情報に気を付けるものではありません。

宣言的なクラスで単にmycolumn=relationship(OtherTable)と言っても、SAが明白な関係を検出できると仮定すると、mycolumnがリストになることがわかりました。だから、実際にオブジェクトがその子ではなくその親にリンクしたい場合は、子テーブルにparent=relationship(OtherTable, backref='children', remote_side=OtherTable.id)を定義することができます。これは、親子関係の両方向を定義します。

+0

お返事ありがとうございます。 私は試みましたが、私はまだ同じエラーが発生します。 NodeTypeBクラスをどのように変更する必要がありますか。 コードでは、Employee.manager_idとEmployee.managerをクラス定義外に定義します。しかし、私のコードにあなたの提案では、あなたはしませんでした。 申し訳ありませんが、私はそれを明確にしていないと思います。 よろしくお願いいたします。 –

+0

SQLAlchemyのドキュメントでは、evalされた文字列を提供することができ、自己参照構文エラーを回避できると言います。しかし、私はそれを試みたことはありません。 – wberry

+0

NodeTypeBでは、外部キーはasset_baseになります。それはタイプミスだと思うのですが、投稿する前に名前を変更するのを忘れてしまいました。私はあなたがForeignKey( 'asset_base.id')をForeignKey(NodeTypeA.id)に変更すると、それは私の動作例に近くなると思います。 – wberry