sqlalchemy 多对多关系(标签系统)
我有三个表:file
、file_tag
和tag
。
现在我想找到所有带有标签ID为1
和3
的文件。
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]))
问题是,它给我显示的是所有带有标签1
或3
的文件,我想看到的是同时带有标签1
和3
的文件。
它生成的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
结果我得到了文件2
、3
和4
,但我应该只得到文件2
和4
。
如果可以的话,我不想使用子查询,我听说它们比较慢;)
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)))
它包含一个子查询,但我觉得如果不使用它们,你想要的结果是达不到的。