首页 > 解决方案 > SqlAlchemy ORM中join的理解

问题描述

我实际上有工作代码,但我想知道是否可以用 Sqlalchmey ORM 方式完成更多工作。

我有这 3 张桌子:

class NodesModel(db.Model):
    __tablename__ = 'nodes'

    id = db.Column(db.BigInteger, primary_key=True)
    project_id = db.Column(db.BigInteger, db.ForeignKey('projects.id'))
    name = db.Column(db.String)

    posts_nodes = relationship("PostsNodesModel", backref="nodes")
class PostsModel(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.BigInteger, server_default=db.FetchedValue(), primary_key=True)
    project_id = db.Column(db.BigInteger, db.ForeignKey('projects.id'))

    posts_nodes = relationship("PostsNodesModel", backref="posts")
class PostsNodesModel(db.Model):
    __tablename__ = 'posts_nodes'

    post_id = db.Column(db.BigInteger, db.ForeignKey('posts.id'), primary_key=True)
    node_id = db.Column(db.BigInteger, db.ForeignKey('nodes.id'), primary_key=True)

所以我有这个查询,它将查找名称并获取与名称关联的帖子:

return (db.session.query(PostsModel.data_date, NodesModel.topic)
        .join(PostsNodesModel, PostsNodesModel.node_id == NodesModel.id)
        .join(PostsModel, PostsModel.id == PostsNodesModel.post_id)
        .filter(NodesModel.project_uuid == project_uuid)
        .all())

这可行,但我在 SQLAlchemy 中阅读了这个 stackoverflow 问题,“过滤器”与“连接和过滤器”语法有什么区别?

并注意到那个人正在使用该方法

.join(Author, Publisher, Retailer)

那个人说,这种关系会处理链接。

我试图为我的陈述做这件事:

return (db.session.query(NodesModel)
        .with_entities(PostsModel.data_date, NodesModel.topic)
        .join(PostsNodesModel, PostsModel)
        .filter(NodesModel.project_uuid == project_uuid)
        .all())

但当然,它没有用。

因此,在了解有关 Sqlalchemy 的更多信息后,任何人都可以使用上述方法并解释或指出我如何做到这一点的解释吗?

Sqlalchemy“配置关系连接方式”中有这一行指出“relationship() 通常会通过检查两个表之间的外键关系以确定应该比较哪些列来创建两个表之间的连接。” 所以实际上我上面的陈述应该有效。

我已经尝试阅读有关它的文档,但我仍然无法理解它是如何工作的以及如何让它工作。

另一件事,没有父母或孩子,因为我的查询是双向的,我有时会查询帖子以获取链接到该帖子的名称。

谢谢。德斯蒙德

标签: pythonsqlalchemy

解决方案


你可以试试:


query = NodesModel.join(
    PostsNodeModel, PostsNodesModel.node_id == NodesModel.id
).join(
    PostsModel, PostsModel.id == PostsNodesModel.post_id
).filter(
    NodesModel.project_uuid == project_uuid
).with_entities(
 .filter(NodesModel.project_uuid == project_uuid)
)

return query

从调用函数中,您可以简单地调用.all()

def calling_function():
   query = get_query()
   query.all()

推荐阅读