为了账号安全,请及时绑定邮箱和手机立即绑定

相互引用类死锁

相互引用类死锁

牧羊人nacy 2022-05-11 16:32:06
我有两个相互引用的 SQLAlchemy 类声明,所以第一个给出错误,因为第二个尚未声明。Keywith中的记录key_type_id == 4是从一个Entity人Entity通过parent_entity_id.要定义Entity收集所有子实体的关系,我需要添加一个反向引用,但该引用key稍后声明。class Entity(db.Model):    __tablename__ = 'entity'    entity_id = db.Column(db.INTEGER, primary_key=True)    ...    children = db.relationship(        'Entity', secondary=key,        primaryjoin="and_(key.c.entity_id == entity_id, "            "key.c.key_type_id == 4)",        secondaryjoin=(key.c.parent_entity_id == entity_id),        backref=db.backref('key', lazy='dynamic'), lazy='dynamic')class Key(db.Model):    __tablename__ = 'key'    ...    entity_id = db.Column(db.ForeignKey('entity.entity_id'), nullable=False,         index=True)    ...    key_type_id = db.Column(db.ForeignKey('key_type.key_type_id'), index=True)         # 4 for a foreign key    ...    parent_entity_id = db.Column(db.INTEGER, index=True)    ...错误回溯是。ipdb> Traceback (most recent call last):  File "<ipython-input-1-a3063c2d9856>", line 1, in <module>    debugfile('C:/Users/Mark Kortink/Dropbox/Python/projects/metapplica/_dev/Scraps/ooClass2DBs.py', wdir='C:/Users/Mark Kortink/Dropbox/Python/projects/metapplica/_dev/Scraps')  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 856, in debugfile    debugger.run("runfile(%r, args=%r, wdir=%r)" % (filename, args, wdir))  File "C:\ProgramData\Anaconda3\lib\bdb.py", line 585, in run    exec(cmd, globals, locals)  File "<string>", line 1, in <module>  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile    execfile(filename, namespace)  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile    exec(compile(f.read(), filename, 'exec'), namespace)首先,我是否正确声明了 backref 关系?二、如何打破僵局?
查看完整描述

1 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

key您正在使用的模块中不存在该名称。即使您Key首先定义了您的类,实际上也永远不会引用在您的模块范围内Table命名的对象。key认识到这一点,您可以将表的名称作为字符串传递给它的参数relationship(),否则需要在模块范围内引用该名称。

文档

使用声明式扩展时,声明式初始化程序允许将字符串参数传递给 relationship()。这些字符串参数被转换为可调用函数,将字符串评估为 Python 代码,使用声明性类注册表作为命名空间。这允许通过其字符串名称自动查找相关类,并且无需在声明依赖类之前将相关类导入本地模块空间。

也就是说secondary=key,可以声明为secondary="key"。然后,SQLAlchemy 将仅"key"在映射所有类之后尝试将字符串解析为它引用的对象,并且该表将存在于 SQLAlchemy 用于跟踪此类对象的内部注册表中。同样,secondaryjoin=(key.c.parent_entity_id == entity_id)可以定义为secondaryjoin="key.c.parent_entity_id == entity_id"


查看完整回答
反对 回复 2022-05-11
  • 1 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信