sqlalchemy:在过滤或子句中引用 label() 列

6 投票
2 回答
6318 浏览
提问于 2025-04-16 17:09

我正在尝试进行一个查询,这个查询涉及到一个多对多的关系,主要是 bmarks 和 tags 之间的关系,还有一个中间表 bmarks_tags。这个查询包含了几个子查询,并且我需要对某一列进行去重。之后,我想通过去重后的 ID 将结果与另一个表连接起来。

我尝试了几种方法,这个方法看起来最接近:

tagid = alias(Tag.tid.distinct())
test = select([bmarks_tags.c.bmark_id],
              from_obj=[bmarks_tags.join(DBSession.query(tagid.label('tagid'))),
                        bmarks_tags.c.tag_id == tagid])

 return DBSession.execute(qry)

但是我遇到了一个错误:

⇝ AttributeError: '_UnaryExpression' object has no attribute 'named_with_column'

有没有人知道我该如何在 bmarks_tags.tag_id 和 Tag.tid.distinct() 的结果之间进行连接?

谢谢

数据库结构:

# this is the secondary table that ties bmarks to tags
bmarks_tags = Table('bmark_tags', Base.metadata,
    Column('bmark_id', Integer, ForeignKey('bmarks.bid'), primary_key=True),
    Column('tag_id', Integer, ForeignKey('tags.tid'), primary_key=True)
)

class Tag(Base):
    """Bookmarks can have many many tags"""
    __tablename__ = "tags"

    tid = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(Unicode(255), unique=True)

2 个回答

0

很难理解你想要实现什么,不过既然你已经在使用ORM(对象关系映射),而且现在用SQLAlchemy直接写查询的理由不多了,那么你可能应该先建立一个多对多的关系:

bmarks_tags = Table('bmark_tags', Base.metadata,
    Column('bmark_id', Integer, ForeignKey('bmarks.bid'), primary_key=True),
    Column('tag_id', Integer, ForeignKey('tags.tid'), primary_key=True)
)

class Tag(Base):
    """Bookmarks can have many many tags"""
    __tablename__ = "tags"

    tid = Column(Integer, primary_key=True)
    name = Column(Unicode(255), unique=True)

class BMark(Base):
    __tablename__ = 'bmarks'
    bid = Column(Integer, primary_key=True)
    tags = relation(Tag, secondary=bmarks_tags, backref="bmarks")

然后获取你的查询结果,接下来就可以继续操作了:

query = DBSession.query(BMark).join(BMark.tags)

如果不是这样的话,给我们你想要SQLAlchemy生成的实际SQL语句吧。

4

像这样的代码应该可以正常工作:

t = DBSession.query(Tag.tid.distinct().label('tid')).subquery('t')
test = select([bmarks_tags.c.bmark_id], bmarks_tags.c.tag_id == t.c.tid)
return DBSession.execute(test)

撰写回答