You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask应用SQLAlchemy多表查询:获取未被当前用户审核的文件名

解决Flask-SQLAlchemy查询未审核图片的问题

嘿,刚上手Flask和SQLAlchemy遇到关联查询的问题太正常啦,我来帮你理清楚怎么实现你要的需求!

首先,先对照你给出的表结构,我写出对应的ORM模型(你可以根据自己的实际代码调整细节):

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
    user_id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(50))
    last_name = db.Column(db.String(50))

class Picture(db.Model):
    filename = db.Column(db.String(100), primary_key=True)
    picture_type = db.Column(db.String(50))
    painter = db.Column(db.String(100))

class Comment(db.Model):
    # 联合主键,确保一个用户对同一张图只能评论一次
    user_id = db.Column(db.Integer, db.ForeignKey('user.user_id'), primary_key=True)
    filename = db.Column(db.String(100), db.ForeignKey('picture.filename'), primary_key=True)
    comment = db.Column(db.Text)

你的核心需求是:筛选出指定picture_type的图片,且当前用户还没有对这些图片发表过评论(即未审核)。这里给你两种易懂的实现方式,你可以根据场景选择:

方式一:NOT IN + 子查询(直观易懂,适合新手)

这种写法逻辑非常直接:先找出当前用户已经评论过的所有图片文件名,再从Picture表中排除这些文件名,同时筛选指定类型。

# 替换成你的当前用户ID,比如从Flask Session获取:session.get('user_id')
# 如果用Flask-Login,直接用current_user.user_id即可
current_user_id = 1

# 子查询:获取当前用户已评论的所有图片文件名
user_commented_files = db.session.query(Comment.filename).filter(Comment.user_id == current_user_id)

# 主查询:筛选指定类型且不在已评论列表中的图片
unreviewed_pics = Picture.query.filter(
    Picture.picture_type == "你的目标类型",  # 替换成实际要筛选的类型,比如"oil_painting"
    Picture.filename.not_in(user_commented_files)
).all()

# 如果只需要文件名列表(不需要完整的Picture对象),可以用with_entities优化查询
unreviewed_filenames = Picture.query.with_entities(Picture.filename).filter(
    Picture.picture_type == "你的目标类型",
    Picture.filename.not_in(user_commented_files)
).all()
# 把查询结果转成纯字符串列表
unreviewed_filenames = [filename[0] for filename in unreviewed_filenames]

方式二:左连接(Left Join)+ 空值筛选(性能更优)

当数据量较大时,左连接的写法通常比子查询更高效——数据库对连接操作的优化普遍更好。思路是将Picture表和Comment表左连接(关联条件为文件名匹配且评论属于当前用户),然后筛选出没有匹配到Comment记录的图片(也就是用户没评论过的)。

current_user_id = 1

unreviewed_pics = Picture.query.join(
    Comment,
    # 连接条件:文件名相同,且评论属于当前用户
    (Picture.filename == Comment.filename) & (Comment.user_id == current_user_id),
    isouter=True  # 左连接:保留所有Picture记录,即使没有对应的Comment
).filter(
    Picture.picture_type == "你的目标类型",
    Comment.user_id.is_(None)  # 筛选出没有匹配到评论的图片
).all()

# 同样,获取文件名列表的写法:
unreviewed_filenames = Picture.query.with_entities(Picture.filename).join(
    Comment,
    (Picture.filename == Comment.filename) & (Comment.user_id == current_user_id),
    isouter=True
).filter(
    Picture.picture_type == "你的目标类型",
    Comment.user_id.is_(None)
).all()
unreviewed_filenames = [filename[0] for filename in unreviewed_filenames]

小提醒

  • 记得替换代码里的占位符:current_user_id要换成你实际获取当前用户ID的方式,"你的目标类型"换成你要筛选的图片类型值。
  • 如果你的模型字段名和示例有差异(比如picture_type叫img_type),记得对应修改。

内容的提问来源于stack exchange,提问作者Kay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:27:43