gpt4 book ai didi

由于自动关联,SQLAlchemy query.filter 未返回 FROM 子句

转载 作者:行者123 更新时间:2023-11-29 11:49:49 26 4
gpt4 key购买 nike

我是 SQLAlchemy 的初学者,对大量文档感到沮丧。

我有一个新闻源,当对某些内容 对象进行新的修订 时,它会更新。 content 总是至少有一个revision内容通过关联表与1个或多个主题相关。我得到了一组 topic.ids T,我想显示属于 content 中至少有一行的 N 个最近“批准”的修订T 中的一个主题。(“approved”只是revision 的枚举属性)

以下是模型和相关属性:

class Revision(Model):
__tablename__ = 'revision'

class Statuses(object): # enum
APPROVED = 'approved'
PROPOSED = 'proposed'
REJECTED = 'rejected'
values = [APPROVED, PROPOSED, REJECTED]
id = Column(Integer, primary_key=True)
data = Column(JSONB, default=[], nullable=False)
content_id = db.Column(db.Integer, db.ForeignKey('content.id'), nullable=False)

class Content(Model):
__tablename__ = 'content'

id = Column(Integer, primary_key=True)
topic_edges = relationship(
'TopicContentAssociation',
primaryjoin='Content.id == TopicContentAssociation.content_id',
backref='content',
lazy='dynamic',
cascade='all, delete-orphan'
)

revisions = relationship(
'Revision',
lazy='dynamic',
backref='content',
cascade='all, delete-orphan'
)

class TopicContentAssociation(Model):
__tablename__ = 'topic_content_association'
topic_id = Column(Integer, ForeignKey('topic.id'), primary_key=True)
content_id = Column(Integer, ForeignKey('content.id'), primary_key=True)

class Topic(Model):
__tablename__ = 'topic'
id = Column(Integer, primary_key=True)

这是我到目前为止所得到的:

revisions = session.query(Revision).outerjoin(Content).outerjoin(Topic).filter(
~exists().where(
and_(
Topic.id.in_(T),
Revision.status == Revision.Statuses.APPROVED
) )
).order_by(Revision.ts_created.desc()).limit(N)

并且发生了这个错误:

由于自相关,Select 语句没有返回 FROM 子句;指定 correlate( ) 以手动控制相关性。:

SELECT * 
FROM topic, revision
WHERE topic.id IN (:id_1, :id_2, :id_3...)
AND revision.status = :status_1

有趣的是,如果我删除了 and_ 运算符和其中的第二个表达式(第 3、5 和 6 行),错误似乎就消失了。

奖励::) 我还想在每行内容 中只显示一个修订。如果有人多次点击保存,我不希望 Feed 变得困惑。

再次强调,我对 SQLAlchemy(实际上是关系数据库)非常陌生,因此非常感谢针对初学者的回答!

编辑:在 .where 子句后添加 .correlate(Revision) 修复问题,但我仍在努力弄清楚这里到底发生了什么。

最佳答案

这是一个很晚的回复,但我会回复以防有人找到这个主题。

exist 语句中的第二个表达式 (Revision.status == Revision.Statuses.APPROVED) 在查询中第二次调用表 Revision。第一次调用此表是通过编写“session.query(Revision)”

如果我们在 PostgreSQL 中“翻译”您的 exists 语句,它将是:

EXISTS (SELECT 1 
FROM Revision
WHERE topic.id IN (:id_1, :id_2, :id_3...)
AND revision.status = :status_1
)

除非使用别名,否则不允许在同一个查询中调用同一个表两次(FROM Revision)。因此,您可以使用 aliased() 函数创建所需表的别名并解决您的问题。你的代码应该是这样的:

from sqlalchemy.orm import aliased

aliasRev = aliased(Revision)

revisions = session.query(Revision).outerjoin(Content).outerjoin(Topic).filter(
~exists().where(
and_(
Topic.id.in_(T),
aliasRev.status == Revision.Statuses.APPROVED
) )
).order_by(Revision.ts_created.desc()).limit(N)

关于由于自动关联,SQLAlchemy query.filter 未返回 FROM 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35690518/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com