用于更新具有唯一列的许多表的标记的数据库

2024-09-25 12:28:47 发布

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

我对数据库不是很有经验,可能完全走错了方向。你知道吗

我有两个表,链接和标签,以及一个关联表。我想用一个看起来像row = [tag, link]的输入来更新这个数据库,但是要确保我没有添加任何已经存在的标记或链接。所以我首先测试链接是否存在,然后测试标记是否存在,最后测试关联是否存在。你知道吗

表格如下所示:

tagslinks_assoc = Table(
    'tagslinks', Base.metadata,
    # Column('id', Integer, primary_key=True),  # Not sure if this is required
    Column('tagid', Integer, ForeignKey('tags.tagid')),
    Column('linkid', Integer, ForeignKey('links.linkid')))

class Tags(Base):
    __tablename__ = 'tags'    
    tagid = Column(Integer, primary_key=True)
    tag   = Column(String, unique=True)
    links = relationship("Links", secondary=tagslinks_assoc, backref="tags")

class Links(Base):
    __tablename__ = 'links'    
    linkid    = Column(Integer, primary_key=True)
    link      = Column(String, unique=True)

我正在检查链接和标记是否存在:

link = session.query(Links).filter(Links.link == row[1]).first()
tag = session.query(Tags).filter(Tags.tag == row[0]).first()

如果标签和链接都已存在,但尚未连接,如何更新它们之间的关联?你知道吗

sqlalchemy和/或数据库关系中是否存在使整个方法变得多余的东西?你知道吗

为了理解如何创建多对多关系,我在this example工作,但是我的字段都是唯一的。也许他们不应该?你知道吗


Tags: key标记数据库truebase链接taglink
1条回答
网友
1楼 · 发布于 2024-09-25 12:28:47

你就快到了。默认情况下,关系是类似列表的,因此只需附加一个项就可以创建一个新的关联。相反,将它们设置为检测重复项。集合中的东西需要重写__hash__,以便正确地检测重复项。你知道吗

class Tags(Base):
    # ...

    links = relationship(
        'Links', tagslinks_assoc,
        collection_class=set,  # use a set to hold the collection
        backref=backref('tags', collection_class=set)
    )

    def __hash__(self):
        return hash((self.__class__, self.tag))  # any Tag with the same name hashes equal

class Links(Base):
    # ...

    def __hash__(self):
        return hash((self.__class__, self.link))

现在获取标签,并将其添加到链接中。如果它已经存在,什么也不会发生。你知道吗

tag = session.query(Tags).filter(Tags.tag == 'my_tag').first()
link = session.query(Link).filter(Links.link == 'my_link').first()

link.tags.add(tag)  # if it's already present, the hash will compare equal and nothing will happen
session.commit()

请参阅有关collection_class的文档。你知道吗

关于tagslinks\u assoc表,在大多数情况下,每个表都应该有一个主键。在本例中,键将是tagid和linkid的组合。你知道吗

tagslinks_assoc = Table(
    'tagslinks', Base.metadata,
    Column('tagid', Integer, ForeignKey('tags.tagid'), primary_key=True),
    Column('linkid', Integer, ForeignKey('links.linkid'), primary_key=True)
)

相关问题 更多 >