我该如何更改SQLAlchemy查询?

时间:2017-07-13 22:48:06

标签: python mysql sqlalchemy

我是新手使用python并尝试使用SQLAlchemy连接我的数据库。我有一些表格可以从新闻报道中获取信息。我做的第一件事是在sql控制台中运行查询,然后使用SQLAlchemy构建它。

我正在尝试基于标签进行搜索,但我需要所有故事的标签,我在sql控制台中测试了以下查询,它运行正常:

SELECT s.id as id, s.date as date, s.image as image, so.  name as source_name, 
so.logo as source_logo, s.title as title, s.url as url, (
    SELECT GROUP_CONCAT(t.name SEPARATOR ', ') 
    FROM tag as t 
    WHERE NOT (t.name LIKE '%trump%' OR t.name LIKE '%president%') 
AND t.story_id = s.id ORDER BY t.weight) as tags 
FROM story as s, source as so 
WHERE s.id IN (
    SELECT DISTINCT(t.story_id) 
    FROM tag as t  
    WHERE t.name LIKE '%trump%' OR t.name LIKE '%president%'
    ORDER BY t.story_id) 
AND s.date BETWEEN NOW() - INTERVAL 50 DAY AND NOW() AND s.source_id = so.id

然后我尝试使用SQLAlchemy构建该查询,问题是“group_concat”函数将每行中的所有标记连接在一起,而不是连接每行的标记

story = DbAdapter.story_table.c
source = DbAdapter.source_table.c
tag = DbAdapter.tag_table.c

sel = select([story.id, story.date, story.image, source.name, 
source.logo, story.title, story.url,
(select([func.group_concat(tag.name)])
.where(and_(not_(or_(*params)), story.id == tag.story_id))
.order_by(tag.weight)).alias("tags")])
.where(and_(and_(story.id.in_(select([tag.id.distinct()])
.where(or_(*params))), story.date.between(five_weeks_ago, current_time)), 
story.source_id == source.id))
.order_by(story.id)

控制台以sql格式打印查询

SELECT story.id, story.date, story.image, source.name, source.logo, story.title, 
story.url, tags.group_concat_1 
FROM story, source, (
    SELECT group_concat(tag.name) AS group_concat_1 
    FROM tag, story 
    WHERE NOT (tag.name LIKE %s OR tag.name LIKE %s OR tag.name LIKE %s) 
    AND story.id = tag.story_id ORDER BY tag.weight) AS tags 
WHERE story.id IN (SELECT DISTINCT tag.id 
FROM tag 
WHERE tag.name LIKE %s OR tag.name LIKE %s OR tag.name LIKE %s) 
AND story.date BETWEEN %s AND %s AND story.source_id = source.id 
ORDER BY story.id

我看到的唯一区别是SQLAlchemy创建了这个新查询,它将“Select Group_Concat”查询从ATTRIBUTES移动到FROM语句。

我的SQLAlchemy查询是否正确?

1 个答案:

答案 0 :(得分:2)

您需要使用.label(),而不是.alias()

.label()将子查询别名为标量表达式(即它位于SELECT列表中),而.alias()将子查询别名为表表达式(即它位于{{{} 1}} list)。