如何解决我的 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 举报,一经查实,本站将立刻删除。