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

时间:2014-05-15 07:19:46

标签: python sql python-3.x sqlalchemy

我有三张牌桌:filefile_tagtag 现在,我想找到所有包含ID为13的标记的文件。

Table: file Table: file_tag Table: 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

如果可能,我不想使用subquerys,我听说它们很慢;)

1 个答案:

答案 0 :(得分: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)))

它包含一个子查询,但我认为如果不使用它们就不可能达到你想要的效果。