对加入SqlAlchemy ORM的理解

2024-09-29 19:19:08 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我有三张桌子:

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())

这是可行的,但我读了这个stackoverflow问题In SQLAlchemy what is the difference between the "filter" vs "join and filter" syntax?

注意到有人在用这个方法

.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()通常会通过检查两个表之间的外键关系来创建两个表之间的联接,以确定应该比较哪些列。”因此实际上,我上面的语句应该起作用。你知道吗

我已经试过阅读关于它的文档,但我仍然没有进一步了解它是如何工作的,以及如何让它工作。你知道吗

另一件事,由于我的查询是双向的,所以没有父级或子级,有时我会查询帖子以获取链接到此帖子的名称。你知道吗

谢谢。 德斯蒙德


Tags: keyprojectidtruedbcolumnnodesposts
2条回答

在benvc的帮助下,我一直在寻找和思考,我找到了答案。你知道吗

我的重写模型:

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'))

    post = relationship("PostsModel", back_populates="nodes")
    node = relationship("NodesModel", back_populates="posts")
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'))

    nodes = relationship("PostsNodesModel", back_populates="post")
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)

    posts = relationship("PostsNodesModel", back_populates="node")

查询:

return (db.session.query(PostsModel.data_date, NodesModel.topic)
        .join('nodes', 'node')
        .filter(NodesModel.project_uuid == project_uuid)
        .all())

nodes和node(在join语句中)使用PostsModel中的nodes变量,node是PostsNodesModel中的变量。你知道吗

有趣的是,必须先放置节点。如果您反转排列(即join('node','nodes'),Sqlalchemy声明PostsModel中没有node属性。如查询中所述,此查询从PostsModel读取到NodesModel。以下方法也适用:

return (db.session.query(NodesModel.topic, PostsModel.data_date)
        .join('posts', 'post')
        .filter(NodesModel.project_uuid == project_uuid))

这将创建从NodesModel到PostsModel的join语句,join排列反映了这一点。你知道吗

您可以尝试:


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()

相关问题 更多 >

    热门问题