whe*_*kie 6 sql postgresql sqlalchemy
我是一个初学者 SQLAlchemy 用户,对大量文档感到沮丧。
我有一个新闻源,当对某些内容对象进行新修订时会更新该新闻源。内容总是至少有一个修订版。内容通过关联表与 1 个或多个主题相关。我在给定一组topic.id式T,想展现N个最近的“批准”属于行中的修订内容是至少有一个话题在T.(“认可”只是一个枚举属性在修订)
以下是模型和相关属性:
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)
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所得到的:
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)
Run Code Online (Sandbox Code Playgroud)
这个错误正在发生:
由于自相关,Select 语句没有返回 FROM 子句;指定 correlate(<tables>) 以手动控制相关性。:
SELECT *
FROM topic, revision
WHERE topic.id IN (:id_1, :id_2, :id_3...)
AND revision.status = :status_1
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果我删除 and_ 运算符和其中的第二个表达式(第 3、5 和 6 行),错误似乎消失了。
奖励: :) 我还想每行内容只显示一个修订版。如果有人多次点击保存,我不希望提要混乱。
同样,我对 SQLAlchemy(实际上是关系数据库)非常陌生,因此非常感谢针对初学者的答案!
编辑:.correlate(Revision)在.where条款修复后添加,但我仍在努力弄清楚这里到底发生了什么。
这是一个很晚的回复,但我会回复以防有人发现这个话题。
存在语句中的第二个表达式 (Revision.status == Revision.Statuses.APPROVED) 在查询中第二次调用表 Revision。你第一次调用这个表是通过写“session.query(Revision)”
如果我们在 PostgreSQL 中“翻译”您的存在语句,它将是:
EXISTS (SELECT 1
FROM Revision
WHERE topic.id IN (:id_1, :id_2, :id_3...)
AND revision.status = :status_1
)
Run Code Online (Sandbox Code Playgroud)
除非您使用别名,否则不允许在同一个查询中两次调用同一个表(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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3422 次 |
| 最近记录: |