11

pbx_point列を持つ親テーブルがありpoint_typeます。と呼ばれる子テーブルもあり、を指すpbx_routeという列があります。point_idpbx_point

sqlalchemy の結合テーブル継承を使用して、これら 2 つのテーブルを宣言型ベースで関連付け、多態的継承を使用したいと考えています。

pbx_pointこれは問題なく動作します。というか、次の追加の制約がなければ、問題なく動作initial_route_idpbx_routeます。

以下でもリフレクションを使用していますが、データベースは上記のとおりです。私が得るエラーはです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.

「舞台裏」の宣言型ベースは、マップされた両方のクラスで relationship() 属性を作成しているため、これは理にかなっています。pbx_route.point_idparent_id リンクとして選択したいのですが、pbx_point.initial_route_id列も表示されます。私がこの Relationship() を作成していた場合、これは簡単に修正できますが、そうではありません。宣言型継承システムはそうです。

必要な外部キーを指定できるようにする__mapper_args__など、に渡すことができる追加の引数はありますか? polymorphic_parent_colそうでない場合、どうすればこの問題を回避できますか?

ありがとう。

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

これは私が得ているスタックトレースです:

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.

これは、mapper.py * の 1032 行目で停止していることを示しています。上記の数行は、マッパー kwarg を参照してinherit_conditionいます。これは、私が必要としているようです。

[*]: バージョン 1.3.11 に調整されたソース リンク (以前の URL は 404 になりました)

4

1 に答える 1

11

キーはinherit_conditionマッパーへの引数です。ポリモーフィック情報は、実際にはこのステップとは何の関係もありません。

修正されたモデル:

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

引数で使用するには、列idと列を追加する必要がありました。リフレクションだけでこれを行う方法もありそうですが、これはひどい障害ではありません。point_idinherit_condition

于 2013-02-15T19:18:17.213 に答える