在sqlalchemy中需要有关联接的帮助

时间:2010-12-21 18:23:12

标签: python join sqlalchemy

我是Python和SQL Alchemy的新手,但不是底层的开发和数据库概念。我知道我想做什么以及我是如何手动完成的,但我正在努力学习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'))

我不断得到关于没有外键关系的错误,这似乎是我明确定义的。我看到了一些关于确保我得到正确的'加入',我正在使用'来自sqlalchemy.orm导入加入',但仍然没有运气。

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文档试图自己解决这个问题。

我非常感谢能够指出我所缺少的人。

1 个答案:

答案 0 :(得分:1)

看来我仍然得到了错误的连接版本,甚至在sqlalchemy.orm下导入了一个。我这样做是为了解决这个问题:

from sqlalchemy.orm.util import join as join_

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

这真的是“最合适的”解决方案,还是我错过了Python的一些细微差别?由于我还在学习,我想按照经验丰富的人的建议,采取“最正确”的方式。感谢。