So, there are a few questions and answers that touch on this issue but I cannot reconcile them exactly with what I'm trying to achieve.
Here, here and here
I have a set of models that are self-referential and inherited. This is the basic design.
class BaseUser(db.Model):
id = db.Column(db.Integer, primary_key=True, nullable=False)
org = db.Column(db.Boolean, default=False, nullable=False)
# Shared Fields
__mapper_args__ = {
'polymorphic_on': org,
}
class Customer(BaseUser):
# Customer Fields
__mapper_args__ = {
'polymorphic_identity': 0
}
class Organization(BaseUser):
# Organization Fields
__mapper_args__ = {
'polymorphic_identity': 1
}
class CustomerOrganization(db.Model):
user_id = db.Column(db.ForeignKey('customer.id', ondelete=CASCADE, onupdate=CASCADE), primary_key=True, nullable=False)
org_id = db.Column(db.ForeignKey('customer.id', ondelete=CASCADE, onupdate=CASCADE), primary_key=True, nullable=False)
I've tried a few different ways to create an "orgs" and a "members" relationship on each of these types. Any advice on how to define the relationsihp()
attributes?
It can be done using primaryjoin
and secondaryjoin
properties. Relevant documentation is here.
Example:
customer_organization = Table(
'base_user_customer_organization', ModelBase.metadata,
Column('user_id', Integer, ForeignKey('base_user.id')),
Column('org_id', Integer, ForeignKey('base_user.id'))
)
class BaseUser(ModelBase):
__tablename__ = 'base_user'
id = Column(Integer, primary_key=True, nullable=False)
org = Column(Boolean, default=False, nullable=False)
# Shared Fields
__mapper_args__ = {
'polymorphic_on': org,
}
customers = relationship(
"BaseUser",
backref=backref('organization', order_by=id),
secondary=customer_organization,
primaryjoin=id==customer_organization.c.org_id and org==True,
secondaryjoin=id==customer_organization.c.user_id and org==False
)
class CustomerUser(BaseUser):
# Customer Fields
__mapper_args__ = {
'polymorphic_identity': False
}
class OrganizationUser(BaseUser):
# Organization Fields
__mapper_args__ = {
'polymorphic_identity': True
}
And test:
sql = sqldb.get_session()
customer1 = sqldb.system.CustomerUser()
sql.add(customer1)
customer2 = sqldb.system.CustomerUser()
sql.add(customer2)
organization = sqldb.system.OrganizationUser()
organization.customers = [customer1, customer2]
sql.add(organization)
sql.commit()
# function prints all table data
print get_sql_table_data(sqldb.system.BaseUser)
print organization.customers
print customer1.organization
print customer2.organization
Output:
[{'org': False, 'id': 1}, {'org': False, 'id': 2}, {'org': True, 'id': 3}]
[<CustomerUser(id=1, org=False)>, <CustomerUser(id=2, org=False)>]
[<OrganizationUser(id=3, org=True)>]
[<OrganizationUser(id=3, org=True)>]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With