sqlalchemy 多对多关系(标签系统)

1 投票
1 回答
799 浏览
提问于 2025-04-18 06:38

我有三个表:filefile_tagtag
现在我想找到所有带有标签ID为13的文件。

表:file 表:file_tag 表:tag

class File_Tag(Base):
    __tablename__ = 'file_tag'

    id = Column(Integer, primary_key=True)
    file_id = Column('file_id', Integer, ForeignKey('file.id'))
    tag_id = Column('tag_id', Integer, ForeignKey('tag.id'))


class File(Base):
    __tablename__ = 'file'

    id = Column(Integer, primary_key=True)
    name = Column(String(255))
    tags = relationship('File_Tag')

class Tag(Base):
    __tablename__ = 'tag'

    id = Column(Integer, primary_key=True)
    name = Column(String(255))
    files = relationship('File_Tag')

这是我现在的代码:

session.query(File).join(File.tags).filter(File_Tag.tag_id.in_([1, 3]))

问题是,它给我显示的是所有带有标签13的文件,我想看到的是同时带有标签13的文件。

它生成的SQL查询看起来是这样的:

SELECT file.id   AS file_id,
  file.name      AS file_name,
  file.sha1      AS file_sha1,
  file.import_id AS file_import_id
FROM file
INNER JOIN file_tag
ON file.id             = file_tag.file_id
WHERE file_tag.tag_id IN (1, 3)
GROUP BY file.id

结果我得到了文件234,但我应该只得到文件24

如果可以的话,我不想使用子查询,我听说它们比较慢;)

1 个回答

0

请试试这个:

SELECT file.id   AS file_id,
  file.name      AS file_name,
  file.sha1      AS file_sha1,
  file.import_id AS file_import_id
FROM file
INNER JOIN file_tag
ON file.id            = file_tag.file_id
WHERE file_tag.tag_id =1
AND file_tag.file_id IN
  (SELECT file_id FROM file_tag WHERE tag_id=3
  )
GROUP BY file.id;

另外,sqlalchemy 应该是这样的:

subq=session.query(File_Tag).filter(File_Tag.tag_id=3);
session.query(File).join(File.tags).filter((File_Tag.tag_id=1)&(File_Tag.file_id.in(subq)))

它包含一个子查询,但我觉得如果不使用它们,你想要的结果是达不到的。

撰写回答