如何插入多对多记录数据?

Posted

技术标签:

【中文标题】如何插入多对多记录数据?【英文标题】:How to insert many to many record data? 【发布时间】:2019-12-18 06:35:27 【问题描述】:

请考虑以下用例。

Post 模型和Tag 模型。它们之间都有many-to-many 关系。一个post 可以有多个tags,而一个tag 可以有多个posts

为了实现这个用例,我实现了一个名为 PostTag 的映射表,如下所示

from database.base import Base
from sqlalchemy import Column, ForeignKey, Integer
from sqlalchemy.orm import relationship
from .model_post import ModelPost
from .model_tag import ModelTag


class PostTag(Base):
   __tablename__ = 'posttag'
   post_id = Column("post_id",Integer, ForeignKey('post.id'), primary_key = True)
   tag_id = Column("tag_id",Integer, ForeignKey('tag.id'), primary_key = True)

通过此设置,我可以成功查询给定post 的所有tags,反之亦然,但我不知道为给定posttag 添加新关联。

请看下面的截图,了解我如何查询相关的tagsposts

如果我在这里遗漏了什么,请告诉我。

谢谢

【问题讨论】:

您在创建记录时不使用 PostTag,如果您建立了关系,SQL Alchemy 会为您执行此操作。您的关系字段是一个列表,您将实例附加到它(如果您将其命名为 tags):post.tags.append(tag)。会话提交后,它将在您的posttag 表中创建。 感谢您的帮助。你能告诉我,我如何在查询中传递tag 值,以便我可以将它添加到 postTag 表并与帖子建立关系。谢谢 创建过程中不涉及查询,只是将一个实例附加到列表中。通过其 id 从数据库中检索 ModelTag 实例或使用 tag = ModelTag() 创建一个新实例并附加它。 假设,我有一个现有的标签和一个现有的帖子。现在在更新帖子期间,我想将其分配给现有标签。我想我需要传递标签,以便在帖子和标签之间创建关联。 不确定我是否理解。如果不是关于post.tags.append(tag),那么它可能是关于tag.posts.append(post),其中tagsposts 是关系字段的名称。 【参考方案1】:

我偷看了一些我的旧代码,设置模型如下:

from sqlalchemy.orm import sessionmaker

posttag = Table(
    "posttag",
    Base.metadata,
    Column("id", INTEGER, Sequence("seq_posttag_id"), primary_key=True),
    Column("post_id", INTEGER, ForeignKey("post.id")),
    Column("tag_id", INTEGER, ForeignKey("tag.id")),
)


class ModelTag(Base):
    __tablename__ = "tag"

    id = Column(INTEGER, Sequence("seq_tag_id"), primary_key=True)
    name = Column(VARCHAR(40), nullable=False)


class ModelPost(Base):
    __tablename__ = "post"

    id = Column(INTEGER, Sequence("seq_post_id"), primary_key=True)
    name = Column(VARCHAR(100), nullable=False)
    tags = relationship(Tag, secondary=posttag)

所以当你创建一个新的 Post 时,你可以添加一个标签而不直接引用 posttag 表:

post = Post(name="foo")

tag = session.query(ModelTag).filter_by(name='some').first()
post.append(tag)

session = Session()
session.add(post)
session.commit()

【讨论】:

哦,这是 sqlalchemy。我对 graphql 的 graphene-sqlalchemy 更感兴趣。 那是the same。 好的 - 那么我还有一个问题 - 我如何从我的 graphql 查询中传递 some ?我相信some 在您在这里的查询中是硬编码的。每当我添加/更新帖子时,我都需要从查询中传递一个标签。 这是一个示例,其中我得到了一个由我组成的名为 name 的字段过滤的 ModelTag 实例。您应该找到通过您在其中获得的字段,通过您从查询中获得的值来定位不同 ModelTag 实例的方法。无论您以何种方式获得 ModelTag 的单个实例,它都适合,您可以将其附加到某个 MoelPost 实例。

以上是关于如何插入多对多记录数据?的主要内容,如果未能解决你的问题,请参考以下文章

实体框架:多对多插入重复

在不使用实体框架的多对多中插入记录

Flask sqlalchemy 多对多插入数据

Jpa多对多如何仅将数据插入2个表

sql 多对多关系中插入行时如何解决死锁问题?

多对多实体框架和存储库模式插入/更新