2015-12-22 183 views
20

因此,有幾個問題和答案涉及這個問題,但我無法完全調和它們與我試圖實現的內容。SQLALchemy多態模型的多對多模型關係配置

Hereherehere

我有一組模型是自我指涉和繼承。這是基本設計。

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) 

我已經嘗試了幾種不同的方法來創建一個「單位啓用」,並在這些類型的「成員」的關係。有關如何定義relationsihp()屬性的任何建議?

回答

5

它可以使用primaryjoinsecondaryjoin屬性來完成。相關文檔是here

實施例:

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 
    } 

和測試:

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 

輸出:

[{'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)>] 
+0

1如前所述單個多態表保存兩個類,這裏​​的多對多關係表使用back-ref作爲集合屬性公開,我認爲它是標準的 – jayprich