加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何使用SQLAlchemy在PostgreSQL ARRAY中的某个位置选择值?

发布时间:2020-12-13 16:01:19 所属栏目:百科 来源:网络整理
导读:对于嵌套注释系统,我使用Comment模型中的以下定义将树结构存储在PostgreSQL表中: path = sa.Column(ARRAY(sa.Integer)) 这会将注释的所有ID存储在当前注释的路径中.因此,如果id为15的注释是11和13的子项,那么它的路径将是[11,13,15]. 现在我想找到并计算孩
对于嵌套注释系统,我使用Comment模型中的以下定义将树结构存储在PostgreSQL表中:

path = sa.Column(ARRAY(sa.Integer))

这会将注释的所有ID存储在当前注释的路径中.因此,如果id为15的注释是11和13的子项,那么它的路径将是[11,13,15].

现在我想找到并计算孩子的评论.所以为了找到评论11的所有孩子,包括我自己,我想生成如下的SQL:

SELECT id,path FROM comments WHERE path[1] = 11;

在我的数据库中,这很快就会返回一组很好的注释11及其子代.

通过上面的例子,如果我想抓住评论的孩子,我可以使用以下SQL:

SELECT id,path FROM comments WHERE path[1] = 11 AND path[2] = 13;

如何使用SQLAlchemy生成此SQL?

我已经使用filter_by()和filter()进行了攻击而没有太大的成功……这些都不起作用:

q = Comment.query.filter(path[1] == 11)
> NameError: name 'path' is not defined

q = Comment.query.filter_by(path[1] = 11)
> SyntaxError: keyword can't be an expression

我不想为这个查询编写自定义SQL,但如果这是唯一的方法,那么请给出一些关于如何最佳构造的指示.

编辑1

确认我正在使用SQLAlchemy 0.7 – 所以使用此版本工作(周围)的答案会更有帮助.

我意识到,对于上面的评论实现,没有必要在确切的位置找到id号,在任何位置找到它们也可以工作.所以关于如何创建SQLAlchemy来生成这样的东西的任何输入都会很好:

SELECT id,path FROM comments WHERE 11 = ANY (path);

那可能吗?

解决方法

这只能从SQLAlchemy 0.8开始工作(编写本文时的beta2):

from sqlalchemy.dialects import postgresql

class Comment(Base):
    __tablename__ = 'comments'
    id = Column(Integer,primary_key=True)
    path = Column(ARRAY(Integer))

q = Comment.query.filter(Comment.path[1] == 11)
# This is just to demonstrate how compiled query would look like.
print q.statement.compile(dialect=postgresql.dialect())

输出:

SELECT comments.id,comments.path 
FROM comments 
WHERE comments.path[%(path_1)s] = %(param_1)s

更新

SA邮件列表中最近有一个关于如何为Postgres数组创建= ANY(和相关)查询的discussion.即使这些例子是为0.8写的,它也应该在0.7中工作.这是一个有效的实现= ANY为0.7(已测试):

from sqlalchemy.sql import literal,tuple_

# There's already built-in any() function in Python,we don't want to
# shadow that.
def any_(value,col):
    return literal(value).op('= ANY')(tuple_(col))

q = Comment.query.filter(any_(11,Comment.path))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读