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

发布于 2024-11-05 13:16:21 字数 1104 浏览 0 评论 0原文

我正在尝试执行一个查询,该查询可以通过 bmarks_tags 辅助表来处理 bmarks 和标签之间的多对多关系。该查询涉及多个子查询,我需要区分一列。我稍后想通过 DISTINCT'd 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)

I'm trying to perform a query that works across a many->many relation ship between bmarks and tags with a secondary table of bmarks_tags. The query involves several subqueries and I have a need to DISTINCT a column. I later want to join that to another table via the DISTINCT'd ids.

I've tried it a few ways and this seems closest:

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)

But I get an error:

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

Does anyone know how I can perform the join across the bmarks_tags.tag_id and the result of the Tag.tid.distinct()?

Thanks

Schema:

# 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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

恋竹姑娘 2024-11-12 13:16:21

像这样的东西应该有效:

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)

Something like this should work:

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)
得不到的就毁灭 2024-11-12 13:16:21

很难说出你想要完成什么,但既然你无论如何都在使用 orm (而且现在没有太多理由在 sa 中使用裸选择),你可能应该从建立一个多对多开始关系:

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。

It is hard to tell what you are trying to accomplish, but since you are using orm anyways (and there is not much reason anymore to go with bare selects in sa these days), you should probably start by establishing a many-to-many relation:

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")

Then get your query and go from there:

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

If not, give us the actual sql you are trying to make sqlalchemy emit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文