SQLAlchemy多个反向引用导致问题

2024-10-04 11:23:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在将SQLAlchemy与Python(链接到MySQL数据库)一起使用,并且有一个小的设计问题,它本身就是一个backref问题

所以情况是这样的。我有一个SearchGroup,其中包含TargetObject和SearchObjects。这些都是多对多关系,因此SearchGroup表附带了两个关联表,每个表对应一个。对于任何SearchGroup,SearchObject的时间相同,但TargetObject的时间不同。到现在为止,一直都还不错。这里的整体思想是,一个SearchObject只是一个包含几个其他变量的字符串,一个SearchGroup将所有这些变量与给定的字符串进行比较,然后,如果存在匹配项,则提供目标对象

现在来看一些代码:这三个类的声明,尽管为了简洁起见隐藏了父逻辑:

class AssocTable_GroupCMClassesGrades_Grades(AssociationTable_Group_TargetObjectsParent, med.DeclarativeBase):
    __tablename__ = 'AssocTable_GroupCMClassesGrades_Grades'
    _groupsTableName = 'SearchGroup_CMClasses_Grades'
    _targetObjectsTableName = 'Grades'

class AssocTable_GroupCMClassesGrades_SearchObjects(AssociationTable_Group_SearchObjectsParent, med.DeclarativeBase):
    __tablename__ = 'AssocTable_GroupCMClassesGrades_SearchObjects'
    _groupsTableName = 'SearchGroup_CMClasses_Grades'
    _searchObjectsTableName = 'SearchObjects'

class SearchGroup_CMClasses_Grades(SearchObjectGroupParent, med.DeclarativeBase):
    __tablename__ = 'SearchGroup_CMClasses_Grades'
    targetAssociatedTargetObjectTableName = 'AssocTable_GroupCMClassesGrades_Grades'
    targetAssociatedSearchObjectTableName = 'AssocTable_GroupCMClassesGrades_SearchObjects'
    targetClassName = 'Grade'
    myClassName = 'SearchGroup_CMClasses_Grades'
    searchObjectClassName = 'SearchObject'
    searchObjectChildrenBackRefName = 'Groups'

上面两个是关联表,下面是主类。字符串用于设置各种外键和关系等

让我们看一个具体的例子,这对问题至关重要:

@declared_attr
def searchObject_childen(cls):
    return relationship(f'{cls.searchObjectClassName}', secondary=f'{cls.targetAssociatedSearchObjectTableName}', backref=f'{cls.searchObjectChildrenBackRefName}')

这在SearchObjectGroupParent类中,正如您所看到的,用于SearchGroup的“子对象”,即SearchObjects

现在开始解决问题。

除了一件事之外,所有这些都很有效。如果我能将您的注意力引向上面的大量代码,以及这一行:

   searchObjectChildrenBackRefName = 'Groups'

正如在第二段发布的代码(声明的_attr one)中所看到的,它设置了一个backref;目标中的属性-它创建该属性,然后填充该属性。无论如何我都不是这方面的专家,所以我不会假装是。要点是:如果我创建另一个SearchObjectGroupParent派生类(如上面的一个)及其关联表,我无法将另一个“Groups”属性放入SearchObject中-事实上,它会抛出一个错误,告诉我:

sqlalchemy.exc.ArgumentError: Error creating backref 'Groups' on relationship 'SearchGroup_CMClasses_Grades.searchObject_childen': property of that name exists on mapper 'mapped class SearchObject->SearchObjects'

有一种不太令人满意的方法可以解决这个问题,那就是每次简单地更改这个名称,但是SearchObject将不会有一个常见的SearchGroup列表。事实上,它将包含每个SearchGroup的“Groups”属性。这会起作用,但会很混乱,我不想这样做。我想说的是‘好吧,如果这个backref已经存在,就用那个吧’。我不知道这是否可能,但我认为这样做可以解决我的问题

编辑:我认为图像可能有助于更好地解释:

图1:我现在拥有的:

enter image description here

从SearchObjectsGroupParent派生的这些对象越多,就越混乱(SearchObject将包含Groups03、Groups04、Groups05等)

图2:我想要的:

enter image description here


Tags: 对象字符串代码属性classclsgroupsgrades