when you use concrete inheritance, you now have three tables: building,
flat, construction. If you'd like these to each have a relationship to
iencumbrance, that's three separate foreign key constraints. Given the
four-column primary key, you'd need to have twelve columns total on
iencumbrance and three constraints. You cannot have a relationship
from the "abstract" class alone, this class does not actually correspond
to any table.
Overall, if you do not need to emit a query of this form:
objects = session.query(iCastradalObject).filter(...).all()
then you should not use concrete inheritance. you should map building /
flat / construction alone. if you'd like them to all have common
features, use iCastradalObject as you are and add the __abstract__ flag,
don't actually use AbstractConcreteBase. Concrete inheritance is
almost never used.
On 05/15/2017 07:03 PM, Никита Крокош wrote:
This is a duplicate from:
http://stackoverflow.com/questions/43972912/abstract-table-concrete-inheritance-could-not-determine-join-condition-between
I've got following example code:
models.py
|
classCadastralObject(Base):
__tablename__ ='cadastral_object'
def__init__(self,cadastral_region,cadastral_district,cadastral_block,cadastral_object):
self.cadastral_region =cadastral_region
self.cadastral_district =cadastral_district
self.cadastral_block =cadastral_block
self.cadastral_object =cadastral_object
# this is a combined PK
cadastral_region =Column(Integer,primary_key=True,index=True)
cadastral_district =Column(Integer,primary_key=True,index=True)
cadastral_block =Column(Integer,primary_key=True,index=True)
cadastral_object =Column(Integer,primary_key=True,index=True)
encumbrances =relationship("Encumbrance")
classEncumbrance(Base):
__tablename__ ='encumbrance'
id =Column(Integer,primary_key=True,index=True)
def__init__(self,cadastral_object):
self.parent_cadastral_region =cadastral_object.cadastral_region
self.parent_cadastral_district =cadastral_object.cadastral_district
self.parent_cadastral_block =cadastral_object.cadastral_block
self.parent_cadastral_object =cadastral_object.cadastral_object
# FK fields
parent_cadastral_region =Column(Integer,nullable=False)
parent_cadastral_district =Column(Integer,nullable=False)
parent_cadastral_block =Column(Integer,nullable=False)
parent_cadastral_object =Column(Integer,nullable=False)
parent_object =relationship(CadastralObject)
__table_args__ =(ForeignKeyConstraint(
[
parent_cadastral_region,
parent_cadastral_district,
parent_cadastral_block,
parent_cadastral_object],
[
CadastralObject.cadastral_region,
CadastralObject.cadastral_district,
CadastralObject.cadastral_block,
CadastralObject.cadastral_object]),
{}
)
|
this code works as intended:
main.py
|
c =CadastralObject(1,2,3,4)
session.add(c)
e =Encumbrance(c)
session.add(e)
session.commit()
print(c.encumbrances)
print(e.parent_object)
|
results:
|
[<app.models.Encumbranceobjectat 0x000001C9B820BCC0>]
<app.models.CadastralObjectobjectat 0x000001C9B820BB00>
|
however, when I'm trying convert my code to Concrete Inheritance:
imodels.py
|
classiCadastralObject(AbstractConcreteBase,Base):
def__init__(self,cadastral_region,cadastral_district,cadastral_block,cadastral_object):
self.cadastral_region =cadastral_region
self.cadastral_district =cadastral_district
self.cadastral_block =cadastral_block
self.cadastral_object =cadastral_object
# this is a combined PK
cadastral_region =Column(Integer,primary_key=True,index=True)
cadastral_district =Column(Integer,primary_key=True,index=True)
cadastral_block =Column(Integer,primary_key=True,index=True)
cadastral_object =Column(Integer,primary_key=True,index=True)
@declared_attr
defencumbrances(self):
returnrelationship("iEncumbrance")
classBuilding(iCadastralObject):
__tablename__ ='building'
__mapper_args__ ={
'polymorphic_identity':'building',
'concrete':True
}
@declared_attr
defencumbrances(self):
returnrelationship("iEncumbrance")
classFlat(iCadastralObject):
__tablename__ ='flat'
__mapper_args__ ={
'polymorphic_identity':'flat',
'concrete':True
}
@declared_attr
defencumbrances(self):
returnrelationship("iEncumbrance")
classConstruction(iCadastralObject):
__tablename__ ='construction'
__mapper_args__ ={
'polymorphic_identity':'construction',
'concrete':True
}
classiEncumbrance(Base):
__tablename__ ='iencumbrance'
id =Column(Integer,primary_key=True,index=True)
def__init__(self,cadastral_object):
self.parent_cadastral_region =cadastral_object.cadastral_region
self.parent_cadastral_district =cadastral_object.cadastral_district
self.parent_cadastral_block =cadastral_object.cadastral_block
self.parent_cadastral_object =cadastral_object.cadastral_object
# FK fields
parent_cadastral_region =Column(Integer,nullable=False)
parent_cadastral_district =Column(Integer,nullable=False)
parent_cadastral_block =Column(Integer,nullable=False)
parent_cadastral_object =Column(Integer,nullable=False)
parent_object =relationship(iCadastralObject)
__table_args__ =(ForeignKeyConstraint(
[
parent_cadastral_region,
parent_cadastral_district,
parent_cadastral_block,
parent_cadastral_object],
[
iCadastralObject.cadastral_region,
iCadastralObject.cadastral_district,
iCadastralObject.cadastral_block,
iCadastralObject.cadastral_object]),
{}
)
|
I'm getting an error on "from app.imodels import Building"
|
sqlalchemy.exc.NoForeignKeysError:Couldnotdetermine join condition
between parent/child tables on relationship
iCadastralObject.encumbrances -there are noforeign keys linking these
tables.Ensurethat referencing columns are associated witha
ForeignKeyorForeignKeyConstraint,orspecify a 'primaryjoin'expression.
|
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and
Verifiable Example. See http://stackoverflow.com/help/mcve for a full
description.
---
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to sqlalchemy+unsubscr...@googlegroups.com
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.