【问题标题】:Multiple relationships to the same table with the same backref name与具有相同 backref 名称的同一个表的多个关系
【发布时间】:2019-08-28 09:43:00
【问题描述】:

我正在构建一个项目清单应用程序,其中项目通过某种主项目链接在一起。一个主项目有几个不同的项目。我希望能够从每个项目中访问相应的主项目。一个项目只能链接到一个主项目。

该应用程序是使用 Flask 和 SQLAlchemy 以及 Python 3.6.5 构建的。我已经尝试了几个back_refback_populates 技巧,但我总是得到这个错误:

sqlalchemy.exc.ArgumentError: Error creating backref 'projects' on relationship 'MasterProject.reseller_project': property of that name exists on mapper 'Mapper|Project|projects'

我发现了有关此主题的其他几篇帖子,但backrefs 总是指代不同的名称。如果可能的话,我希望有相同的名字。

这是我的代码:

class Project(db.Model):
    __tablename__ = 'projects'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

class MasterProject(db.Model):
    __tablename__ = 'master_projects'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    manufacturer_pid = db.Column(db.Integer, db.ForeignKey('projects.id'))
    reseller_pid = db.Column(db.Integer, db.ForeignKey('projects.id'))
    distributor_pid = db.Column(db.Integer, db.ForeignKey('projects.id'))
    influencer_pid = db.Column(db.Integer, db.ForeignKey('projects.id'))

    manufacturer_project = db.relationship('Project', foreign_keys=[manufacturer_pid],
                                           backref='master_project')
    reseller_project = db.relationship('Project', foreign_keys=[reseller_pid],
                                       backref='master_project')
    distributor_project = db.relationship('Project', foreign_keys=[distributor_pid],
                                          backref='master_project')
    influencer_project = db.relationship('Project', foreign_keys=[influencer_pid],
                                         backref='master_project')

我想要以下内容:假设p1 是一个项目。我希望能够访问p1.master_project,无论p1 在其主项目中是什么。

【问题讨论】:

    标签: python-3.x sqlalchemy flask-sqlalchemy


    【解决方案1】:

    您的示例似乎适合Class Inheritance Pattern

    您拥有多个从Project 基类继承的项目类型,而不是一种项目类型。然后,来自MasterProject 的关系反向引用都可以指向关系所代表的适当类。

    例如:

    class Project(db.Model):
        __tablename__ = "projects"
    
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        type_ = db.Column(db.String(20), nullable=False)
    
        __mapper_args__ = {"polymorphic_on": type_}
    
    
    class ResellerProject(Project):
    
        __mapper_args__ = {"polymorphic_identity": "reseller"}
    
    
    class ManufacturerProject(Project):
    
        __mapper_args__ = {"polymorphic_identity": "manufacturer"}
    
    
    class DistributorProject(Project):
    
        __mapper_args__ = {"polymorphic_identity": "distributor"}
    
    
    class InfluencerProject(Project):
    
        __mapper_args__ = {"polymorphic_identity": "influencer"}
    
    
    class MasterProject(db.Model):
        __tablename__ = "master_projects"
    
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        manufacturer_pid = db.Column(db.Integer, db.ForeignKey("projects.id"))
        reseller_pid = db.Column(db.Integer, db.ForeignKey("projects.id"))
        distributor_pid = db.Column(db.Integer, db.ForeignKey("projects.id"))
        influencer_pid = db.Column(db.Integer, db.ForeignKey("projects.id"))
    
        manufacturer_project = db.relationship(
            "ManufacturerProject",
            foreign_keys=[manufacturer_pid],
            backref="master_project",
        )
        reseller_project = db.relationship(
            "ResellerProject",
            foreign_keys=[reseller_pid],
            backref="master_project",
        )
        distributor_project = db.relationship(
            "DistributorProject",
            foreign_keys=[distributor_pid],
            backref="master_project",
        )
        influencer_project = db.relationship(
            "InfluencerProject",
            foreign_keys=[influencer_pid],
            backref="master_project",
        )
    

    这里我们仍然只有一个projects 表,但在该表中添加了另一列,用于区分一种类型的项目。 Project 的每个子类通过 __mapper_args__ 字典中的 "polymorphic_identity" 键与唯一的鉴别器相关联。由于每个都是一个单独的类型,它们每个都可以有一个指向 MasterProject 的关系。

    【讨论】:

    • 非常感谢!这正是我一直在寻找的。完美运行!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 2017-03-03
    • 1970-01-01
    • 2013-03-31
    • 2011-09-16
    • 1970-01-01
    相关资源
    最近更新 更多