如何在sqlalchemy中编写group\u concat函数?

2024-04-26 00:44:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用SQLAlchemy重写这个mysql查询:

架构:

CREATE TABLE `posts` (
    `post_id` INT UNSIGNED PRIMARY AUTO_INCREMENT,
    `post_name` VARCHAR(255)
) Engine=InnoDB;

CREATE TABLE `post_tags` (
    `tag_id` INT UNSIGNED PRIMARY AUTO_INCREMENT,
    `tag_name` VARCHAR(255)
) Engine=InnoDB;

CREATE TABLE `post_tags_map` (
    `map_id` INT PRIMARY AUTO_INCREMENT,
    `post_id` INT NOT NULL,
    `tags_id` INT NOT NULL,
    FOREIGN KEY `post_id` REFERENCES `posts` (`post_id`),
    FOREIGN KEY `post_id` REFERENCES `post_tags` (`tag_id`)
) Engine=InnoDB;

查询:

^{pr2}$

以下是我所拥有的,但我一直得到:

1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SEPARATOR /))

rows = DBSession.query(Posts,func.group_concat(Post_Tags.tag_name.op('SEPARATOR')(literal_column('/')))).outerjoin(PostsTagsMap,Posts.post_id==PostsTagsMap.post_id).outerjoin(Post_Tags,PostsTagsMap.tags_id==Post_Tags.tag_id).group_by(Posts.post_id)

Tags: nameidautotagcreatetagstablepost
3条回答

定义自定义函数元素似乎是处理group_concat方法的最简单方法。在

from sqlalchemy.sql import expression
import sqlalchemy
from sqlalchemy.ext import compiler


class group_concat(expression.FunctionElement):
    name = "group_concat"


@compiler.compiles(group_concat, 'mysql')
def _group_concat_mysql(element, compiler, **kw):
    if len(element.clauses) == 2:
        separator = compiler.process(element.clauses.clauses[1])
    else:
        separator = ','

    return 'GROUP_CONCAT(%s SEPARATOR %s)'.format(
        compiler.process(element.clauses.clauses[0]),
        separator,
    )

像这样使用它:

^{pr2}$

在测试上述示例和其他随机源代码时浪费了大量时间,以找出如何更改func.group_concat()中的标准分隔字符","。。。然后你就可以找到一个符合你的直觉的论点了。 例如:

from sqlalchemy import func
#write the query: db.session.query(...
...func.group_concat(Table.column_name, "; ")

所以,修改前面的答案:

^{pr2}$

注意:这是python3.5、SQLite 3、Flask SQLAlchemy 2.3.2(安装了SQLAlchemy 1.0.13)

事实上,你做得对:

DBSession.query(
   Posts, 
   func.group_concat(Post_Tags.tag_name.op('SEPARATOR')(literal_column('/'))))<...>

我不确定到底是怎么回事,因为你的模式似乎无效,你的查询拼错了表名,从错误判断,你试图把python代码输入mysql。在

对于那些像我一样,在google上找到这个页面的人来说,上面的代码应该很有帮助,还有源代码,显然:https://groups.google.com/forum/#!msg/sqlalchemy/eNbOoRJ425s/bScfQVat15EJ

相关问题 更多 >