我正在构建一个项目清单应用程序,其中项目通过某种主项目链接在一起。一个主项目有几个不同的项目。我希望能够从每个项目访问相应的主项目。一个项目只能链接到一个主项目。
该应用程序是使用Flask和SQLAlchemy以及Python 3.6.5构建的。我尝试了几种back_ref
和back_populates
的技巧,但总是遇到此错误:
sqlalchemy.exc.ArgumentError: Error creating backref 'projects' on relationship 'MasterProject.reseller_project': property of that name exists on mapper 'Mapper|Project|projects'
我发现了有关该主题的其他几篇文章,但是backref
总是引用不同的名称。如果可以的话,我希望使用相同的名称。
这是我的代码:
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
是什么。
答案 0 :(得分:0)
您的示例似乎很适合Class Inheritance Pattern。
您有多种从基类Project
继承的项目类型,而不是一种项目类型。然后,来自MasterProject
的关系backrefs都可以指向该关系表示的适当类。
例如:
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
的每个子类都通过"polymorphic_identity"
字典中的__mapper_args__
键与唯一的标识符相关联。由于每个类型都是单独的类型,因此它们每个都可以具有指向MasterProject
的关系。