Python 需要帮助加入sqlalchemy吗

Python 需要帮助加入sqlalchemy吗,python,join,sqlalchemy,Python,Join,Sqlalchemy,我不熟悉Python和SQL炼金术,但不熟悉底层开发和数据库概念。我知道我想做什么,以及如何手动完成,但我正在尝试学习ORM是如何工作的 我有两个表,图像和关键字。Images表包含一个作为其主键的id列,以及一些其他元数据。关键字表仅包含id列(图像外键)和关键字列。我正试图使用声明性语法正确地声明这种关系,我认为我做得是正确的 Base = declarative_base() class Keyword(Base): __tablename__ = 'Keywords'

我不熟悉Python和SQL炼金术,但不熟悉底层开发和数据库概念。我知道我想做什么,以及如何手动完成,但我正在尝试学习ORM是如何工作的

我有两个表,图像和关键字。Images表包含一个作为其主键的id列,以及一些其他元数据。关键字表仅包含id列(图像外键)和关键字列。我正试图使用声明性语法正确地声明这种关系,我认为我做得是正确的

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'))
我不断地发现关于没有外键关系的错误,这对我来说似乎定义得很清楚。我看到了一些关于确保获得正确的“join”的信息,我正在使用“from sqlalchemy.orm import join”,但仍然没有运气

image = session.query(Image).select_from(join(Image, Keyword)).\
        filter(Keyword.keyword == 'boy')
我在查询中添加了特定的join子句来帮助它,尽管据我所知,我不应该这样做

image = session.query(Image).select_from(join(Image, Keyword,
    Image.id==Keyword.id)).filter(Keyword.keyword == 'boy')
所以最后我改变了策略,尝试查询关键词,然后使用反向引用。但是,当我尝试使用“.images”对结果进行迭代时,我得到一个错误,即“image”属性不存在,即使我将其声明为backref

result = session.query(Keyword).filter(Keyword.keyword == 'boy').all()
我希望能够查询一组关键字上唯一的图像匹配集。我就是猜不出我的语法,我花了几天时间阅读SQL Alchemy文档,试图自己解决这个问题


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

看来我仍然得到了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的一些细微差别?由于我还在学习,我想按照经验丰富者的建议,以“最正确”的方式做事。谢谢。

无需使用
连接
,因为在选择
关键字
实体时,根据为
图像
属性定义的关系,相关的
图像
实体将与之一起检索。我尝试过这个方法,效果很好:
[k.image.name for k in session.query(关键字)。filter_by(关键字class='boy')。all()]
但是,如果执行
session.query(图片)
,您确实需要
加入。但是在您的模型中,查询
关键字
实体(只有一个图像)比查询
图像
实体(有许多关键字)更容易。事实上,在“正常形式”的多对多关系中,您将有另一个关键字表和一个中间关系表,其中包含关键字和图像表的外键。但在本例中,这两个表是相同的,因为关键字不需要字符串以外的属性。(因此,在我看来,这是一个很好的关系设计。)