Ho una tabella padre denominata pbx_point
che ha una colonna point_type
. Ho anche un tavolo per bambini chiamato pbx_route
, con una colonna chiamata point_id
che punta a pbx_point
.In sqlalchemy, come posso utilizzare l'ereditarietà della tabella unita polimorfa quando la tabella figlio ha più chiavi esterne alla tabella padre?
mi piacerebbe utilizzare l'ereditarietà tabella unita del sqlalchemy mettere in relazione queste due tabelle via di base dichiarativa, e utilizzare l'ereditarietà polimorfico
Questo funziona bene - o meglio, sarebbe, se non fosse per il seguente vincolo aggiuntivo: pbx_point
ha anche una chiave esterna chiamata initial_route_id
che punta a pbx_route
.
Sto anche utilizzando la riflessione in basso, ma il db è come descritto sopra. L'errore che ottengo è 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.
.
Questo ha senso, poiché la base delcarativa "dietro le quinte" crea un attributo relationship() su entrambe le classi mappate. Mi piacerebbe scegliere pbx_route.point_id
come link parent_id, ma anche la colonna pbx_point.initial_route_id
. Questo sarebbe semplice da risolvere, se stavo creando questa relazione(), ma non lo sono - il sistema di ereditarietà dichiarativa è.
C'è un argomento aggiuntivo che posso passare a __mapper_args__
, ad esempio polymorphic_parent_col
che mi consente di specificare la chiave esterna che desidero? In caso contrario, come posso risolvere questo problema?
Grazie.
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')
Questa è l'analisi dello stack sto ottenendo:
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.
che indica che sta morendo a https://bitbucket.org/sqlalchemy/sqlalchemy/src/7f3494ebad58/lib/sqlalchemy/orm/mapper.py?at=default#cl-517. Alcune righe sopra fanno riferimento al mapper kwarg inherit_condition
, che sembra essere quello di cui ho bisogno.
Ho avuto questo problema esatto e NON sono riuscito a trovarlo nei documenti. Grazie per la risposta. –