在sqlalchemy中需要帮助使用连接

2 投票
1 回答
1836 浏览
提问于 2025-04-16 08:51

我刚开始学习Python和SQL Alchemy,但对开发和数据库的基本概念并不陌生。我知道我想做什么,以及如果手动操作该怎么做,但我想学习ORM是如何工作的。

我有两个表,一个是Images(图片),另一个是Keywords(关键词)。Images表有一个id列,这是它的主键,还有一些其他的元数据。Keywords表只有一个id列(指向Images的外键)和一个关键词列。我想用声明式语法正确地声明这种关系,我觉得我已经做对了。

Base = declarative_base()

class Keyword(Base):
    __tablename__ = 'Keywords'
    __table_args__ = {'mysql_engine' : 'InnoDB'}

    id = Column(Integer, ForeignKey('Images.id', ondelete='CASCADE'),
            primary_key=True)
    keyword = Column(String(32), primary_key=True)

class Image(Base):
    __tablename__ = 'Images'
    __table_args__ = {'mysql_engine' : 'InnoDB'}

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(256), nullable=False)
    keywords = relationship(Keyword, backref='image')

这代表了一种多对多的关系。一个图片可以有多个关键词,而一个关键词也可以关联到多个图片。

我想对我的图片进行关键词搜索。我尝试了以下方法,但没有成功。

从概念上讲,这样做是不错的,但我明白为什么它不工作。

image = session.query(Image).filter(Image.keywords.contains('boy'))

我一直收到关于没有外键关系的错误,而在我看来,这个关系是很明确的。我看到有人提到要确保我使用正确的“连接”,我用的是'from sqlalchemy.orm import join',但仍然没有成功。

image = session.query(Image).select_from(join(Image, Keyword)).\
        filter(Keyword.keyword == 'boy')

我在查询中添加了特定的连接条件来帮助解决这个问题,尽管我理解这本不应该是必要的。

image = session.query(Image).select_from(join(Image, Keyword,
    Image.id==Keyword.id)).filter(Keyword.keyword == 'boy')

最后,我换了个方法,尝试先查询关键词,然后使用反向引用。然而,当我尝试使用'.images'遍历结果时,出现了一个错误,提示'image'属性不存在,尽管我确实把它声明为反向引用。

result = session.query(Keyword).filter(Keyword.keyword == 'boy').all()

我希望能够根据一组关键词查询到独特的图片匹配结果。我就是无法猜出正确的语法,已经花了好几天在阅读SQL Alchemy的文档,试图自己搞明白。

如果有人能指出我遗漏了什么,我将非常感激。

1 个回答

1

看起来我还是得到了错误版本的 join,尽管我已经导入了 sqlalchemy.orm 下的那个。为了解决这个问题,我做了以下操作:

from sqlalchemy.orm.util import join as join_

image = session.query(Image).select_from(join_(Image, Keyword)).\
    filter(Keyword.keyword == 'boy')

这真的是“最正确”的解决方案吗?还是我对 Python 的某些细节理解得不够?因为我还在学习,我希望能按照那些有经验的人建议的“最正确”的方式来做。谢谢。

撰写回答