Flask-SQLAlchemy双关联查询报错:'int object' has no attribute 'users' 解决求助
Flask-SQLAlchemy双关联查询报错:'int object' has no attribute 'users' 解决求助
兄弟,我看了你的代码,问题核心是把外键字段和关联关系属性搞混了,咱们一步步捋清楚怎么解决:
先说说报错原因
你在模板里写了{{N.taggednameId.users.fullname}},但taggednameId是notifications表里存的整数类型外键值,不是关联的Users对象,自然没有users属性,这就是报错的根源。
第一步:修正模型的关系定义
首先得给Notifications和Users之间的双向关联理清楚,同时注意代码规范(模型类名建议大驼峰,多余的__init__删掉,SQLAlchemy会自动处理实例化):
class Users(db.Model): id = db.Column(db.Integer, primary_key=True) fullname = db.Column(db.String(100)) username = db.Column(db.String(100), unique=True) email = db.Column(db.String(100), unique=True) gender = db.Column(db.String(100)) phonenumber = db.Column(db.Integer) role = db.Column(db.String(100)) Password = db.Column(db.String(100)) datecreated = db.Column(db.DateTime, default=datetime.now) # 发起通知的用户关联,backref改成更语义化的'initiator' notif_user = db.relationship('Notifications', foreign_keys="Notifications.userId", backref='initiator') # 被标记的用户关联,指定外键是taggednameId,backref设为'tagged_user' tagged_users = db.relationship('Notifications', foreign_keys="Notifications.taggednameId", backref='tagged_user') class Notifications(db.Model): # 类名大写更符合Python规范 id = db.Column(db.Integer, primary_key=True) userId = db.Column(db.Integer, db.ForeignKey('users.id')) content = db.Column(db.String(100)) taggednameId = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) datecreated= db.Column(db.DateTime, default=datetime.now) # 删掉多余的__init__方法,SQLAlchemy自带实例化逻辑,你写的return self会出问题
第二步:优化查询语句
你的查询不用手动关联userId和Users.id,外键已经帮你关联好了,还可以用joinedload提前加载关联对象,避免N+1查询的性能问题:
from sqlalchemy.orm import joinedload # 一次性加载关联的用户数据,避免模板里懒加载出错 notifications = Notifications.query.options( joinedload(Notifications.initiator), joinedload(Notifications.tagged_user) ).order_by(Notifications.datecreated.desc()).all()
第三步:修改模板代码
现在直接用关系属性访问用户信息,同时处理taggednameId为空的情况:
<table class="table table-hover align-middle"> <thead> <tr> <th class="fw-bold">SN</th> <th class="fw-bold">Name</th> <th class="fw-bold">Notifcation_Content</th> <th class="fw-bold">Tagged name</th> <th class="fw-bold">Date Posted</th> </tr> </thead> <tbody class="table-group-divider"> {% for N in admindata.notifications %} <tr> <td>{{loop.index}}</td> <td>{{N.initiator.fullname}}</td> <!-- 用initiator直接拿到发起通知的用户对象 --> <td>{{N.content}}</td> <!-- 处理被标记用户为空的情况,避免报错 --> <td>{{N.tagged_user.fullname if N.tagged_user else '无'}}</td> <td>{{N.datecreated}}</td> </tr> {% endfor %} </tbody> </table>
额外提醒
- 模型类名尽量用大驼峰(比如
Notifications),符合Python规范,也和SQLAlchemy的默认行为匹配 - 关系命名尽量语义化,比如
initiator、tagged_user,比模糊的users更容易维护 - 别给模型写多余的
__init__,SQLAlchemy的模型已经有完善的初始化逻辑了
内容来源于stack exchange
相关产品推荐
相关产品推荐

