我的 mixin 有 SQLAlchemy 问题! declared_attr 和同义词

问题描述

所以我过去在我的 sqlAlchemy/Python 项目中使用了几个 mixin (declarative_mixin)。

我想为关联的表父级创建一个新的。我想这似乎很简单。在我陷入奇怪的行为之前,让我向您展示我所拥有的:

@declarative_mixin
class AssociationTable_Group_SearchObjectsParent:

_groupsTableName = 'Not defined target groups table name'
_searchObjectsTableName = 'Not defined target search objects table name'

@declared_attr
def group_id(cls):
    return Column('group_id',Integer,ForeignKey(f'{cls.groupsTableName}.ID'),primary_key=True)

@declared_attr
def searchObject_id(cls):
    return Column('searchObject_id',ForeignKey(f'{cls.searchObjectsTableName}.ID'),primary_key=True)

def get_groupsTableName(self):
    return self._groupsTableName

def set_groupsTableName(self,value):
    self._groupsTableName = value

@declared_attr
def groupsTableName(cls):
    return synonym('_groupsTableName',descriptor=property(cls.get_groupsTableName,cls.set_groupsTableName))

def get_searchObjectsTableName(self):
    return self._searchObjectsTableName

def set_searchObjectsTableName(self,value):
    self._searchObjectsTableName = value

@declared_attr
def searchObjectsTableName(cls):
    return synonym('_searchObjectsTableName',descriptor=property(cls.get_searchObjectsTableName,cls.set_searchObjectsTableName))

我已经像以前一样设置了它。但这里的问题在于 group_id 和 searchObject_id。它们在这里的行为相同。

那么当我创建它时会发生什么?很简单,看起来像这样:

class AssocTable_GroupCMClasses_SearchObjects(AssociationTable_Group_SearchObjectsParent,med.DeclarativeBase):
__tablename__ = 'AssocTable_GroupCMClasses_SearchObjects'
_groupsTableName = 'Search_Group_CMClasses'
_searchObjectsTableName = 'SearchObjects'

显然存在这些其他表。

回到行为上来。您看到这不起作用,错误与 group_id 和 searchObject_id 有关。错误是这样的:

sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Search_Group_CMClasses.searchObject_childen - there are no foreign keys linking these tables via secondary table 'AssocTable_GroupCMClasses_SearchObjects'.  Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint,or specify 'primaryjoin' and 'secondaryjoin' expressions.

现在我知道如何解决它了。我尝试的第一件事是检查 _groupsTableName 和 _searchObjectsTableName 是什么。那些是对的。然后我尝试将名称写入代码本身,而不是

@declared_attr
def group_id(cls):
    return Column('group_id',primary_key=True)

原来是:

@declared_attr
def group_id(cls):
    return Column('group_id',ForeignKey(f'Search_Group_CMClasses.ID'),primary_key=True)

我以前使用过第一种方法,并且它在其他情况下也有效。现在我可以做的让它更通用的是添加下划线,所以如果是 cls.groupsTableName(declared_attr),它是 cls._groupsTableName(类属性)。这有效,但我无法弄清楚为什么。同义词不用于此吗?我以前在另一种有效的情况下以同样的方式使用过它们。

事实上,为了完整起见,我将展示该代码

@declarative_mixin
class SearchParent:

id = Column('ID',primary_key=True,autoincrement=True)
searchTerm = Column('SEARCH_TERM',String(50),unique=False)
include = Column('INCLUDE',Boolean)
caseSensitive = Column('CASE_SENSITIVE',Boolean)
group_id = Column('GROUP_ID',Integer)              

_targetTableName = 'Not defined target table name'
_targetClassName = 'Not defined target class name'
_myClassName = 'Not defined class name'

def get_myClassName(self):
    return self._myClassName

def set_myClassName(self,value):
    self._myClassName = value

@declared_attr
def myClassName(cls):
    return synonym('_myClassName',descriptor=property(cls.get_myClassName,cls.set_myClassName))

def get_targetTableName(self):
    return self._targetTableName

def set_targetTableName(self,value):
    self._targetTableName = value

@declared_attr
def targetTableName(cls):
    return synonym('_targetTableName',descriptor=property(cls.get_targetTableName,cls.set_targetTableName))

def get_targetClassName(self):
    return self._targetClassName

def set_targetClassName(self,value):
    self._targetClassName = value

@declared_attr
def target_id(cls):
    return Column('TARGET_ID',ForeignKey(f'{cls.targetTableName}.ID'))

@declared_attr
def targetClassName(cls):
    return synonym('_targetClassName',descriptor=property(cls.get_targetClassName,cls.set_targetClassName))

@declared_attr
def target_object(cls):
    return relationship(f'{cls.targetClassName}',foreign_keys=f'{cls.myClassName}.target_id')

当然是同样的情况!然而这段代码在不使用类变量的情况下也能工作。到底是怎么回事?感谢您阅读并为这么多代码感到抱歉,但我不确定我可以用其他方式演示它。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)