jam*_*esc 5 python postgresql sqlalchemy
对于嵌套注释系统,我使用Comment模型中的以下定义将树结构存储在PostgreSQL表中:
path = sa.Column(ARRAY(sa.Integer))
Run Code Online (Sandbox Code Playgroud)
这会将注释的所有ID存储在当前注释的路径中.因此,如果id15 的评论是11和13的孩子,那么它的路径就是[11,13,15].
现在我想找到并计算孩子的评论.所以为了找到评论11的所有孩子,包括我自己,我想生成如下的SQL:
SELECT id, path FROM comments WHERE path[1] = 11;
Run Code Online (Sandbox Code Playgroud)
在我的数据库中,这很快就会返回一组很好的注释11及其子代.
通过上面的例子,如果我想抓住评论的孩子,我可以使用以下SQL:
SELECT id, path FROM comments WHERE path[1] = 11 AND path[2] = 13;
Run Code Online (Sandbox Code Playgroud)
如何使用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
Run Code Online (Sandbox Code Playgroud)
我不想为这个查询编写自定义SQL,但如果这是唯一的方法,那么请给出一些关于如何最佳构造的指示.
编辑1
确认我正在使用SQLAlchemy 0.7 - 所以使用此版本工作(周围)的答案会更有帮助.
我意识到,对于上面的评论实现,没有必要在确切的位置找到id号,在任何位置找到它们也可以工作.所以关于如何创建SQLAlchemy来生成这样的东西的任何输入都会很好:
SELECT id, path FROM comments WHERE 11 = ANY (path);
Run Code Online (Sandbox Code Playgroud)
那可能吗?
这只能从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())
Run Code Online (Sandbox Code Playgroud)
输出:
SELECT comments.id, comments.path
FROM comments
WHERE comments.path[%(path_1)s] = %(param_1)s
Run Code Online (Sandbox Code Playgroud)
更新
最近在SA邮件列表中讨论了如何= ANY为Postgres数组创建(和相关)查询.即使这些例子是为0.8写的,它也应该在0.7中工作.这是= ANY0.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))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2686 次 |
| 最近记录: |