EB.*_*EB. 11 python polymorphism orm inheritance sqlalchemy
我有一个名为的父表pbx_point有一个point_type列.我还有一个名为的子表pbx_route,其中一个列称为point_id指向pbx_point.
我想使用sqlalchemy的连接表继承来通过声明性基础关联这两个表,并使用多态继承
这样可以正常工作 - 或者更确切地说,如果不是以下附加约束,它也会工作:pbx_point还有一个名为initial_route_id指向的外键pbx_route.
我也在下面使用反射,但db就像我上面所描述的那样.我得到的错误是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..
这是有道理的,因为"幕后"decarative base正在两个映射类上创建一个relationship()属性.我希望它选择pbx_route.point_id作为parent_id链接,但它也会看到pbx_point.initial_route_id列.如果我正在创建这种关系(),这很容易修复,但我不是 - 声明性继承系统.
我可以传递一个额外的参数__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')
Run Code Online (Sandbox Code Playgroud)
这是我得到的堆栈跟踪:
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.
Run Code Online (Sandbox Code Playgroud)
这表明它正在死于https://bitbucket.org/sqlalchemy/sqlalchemy/src/7f3494ebad58/lib/sqlalchemy/orm/mapper.py?at=default#cl-517.上面的几行使得映射器kwarg得到了回报inherit_condition,这似乎是我需要的.
EB.*_*EB. 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)
)
Run Code Online (Sandbox Code Playgroud)
我需要添加id和point_id列以在inherit_condition参数中使用它们.只有使用反射才有可能做到这一点,但这不是一个可怕的障碍.