【发布时间】:2016-06-11 23:00:50
【问题描述】:
我是 SQLAlchemy 的初学者,对大量文档感到沮丧。
我有一个新闻源,它在对某些 content 对象进行新的revision 时更新。 content 始终至少有一个 revision。 content 通过关联表与 1 个或多个 topic 相关。我得到了一组 topic.id 的 T,并且想显示属于 content 中的一行的 N 个最近“已批准”的修订,该修订至少具有T 中的一个 topic。(“已批准”只是 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 行),错误似乎消失了。
BONUS: :) 我还希望每行 content 只显示一个 revision。如果有人多次点击保存,我不希望提要混乱。
再次,我对 SQLAlchemy(实际上是关系数据库)非常陌生,因此非常感谢针对初学者的答案!
编辑:在.where 子句之后添加.correlate(Revision) 可以解决问题,但我仍在努力弄清楚这里到底发生了什么。
【问题讨论】:
-
请发布您正在使用的 sqlalchemy 模型定义,以及您希望 sqlalchemy 生成的所需 SQL。
-
感谢@HaleemurAli - 我已经添加了相关的 SQLAlchemy 模型。请多多包涵,因为我对 sql 和 sqlalchemy 都是新手,这让我很难解决这个问题。这个“相关”运算符(就是它的名字吗?)对我来说是新的,不清楚它对我的查询结果做了什么。解释为什么它修复了描述的错误以及它做了什么将是一个很好的开始!
-
您的示例代码有问题。没有名为
content的表,但是有一个外键引用它。模型Content映射到名为revisions的表,但未指定任何列。在我粗略的检查中,其中指定的关系似乎更好地位于模型TopicContentAssociation。 -
你说得对,@HaleemurAli - 我一定搞砸了我的编辑器的复制/粘贴。我会解决的...
-
@HaleemurAli 我已经经历了几次,希望通过在
Revision中添加缺少的content_id属性来解决您的问题,这是我错误地没有复制/粘贴的。名为Content的模型定义了一个名为revisions的属性,而没有故意进行主连接。我遵循这种模式:docs.sqlalchemy.org/en/latest/orm/backref.html 代表我的revision/content关系。
标签: sql postgresql sqlalchemy