我通过MySQL有三个表:
Item
iid int not null, auto_increment
<several other columns of static data>
primary key (iid)
Source
sid int not null, auto_increment
name varchar(200) not null,
special boolean default false,
<other columns of static data>
primary key (sid)
ItemSource
isid int not null, auto_increment
iid int not null
sid int not null
primary key (isid)
foreign key (iid) references Item (iid)
foreign key (sid) references Source (iid)
对于一个Item,可以有零到无限的源,对于一个Source,可以有零到无限的项。这些表是使用MySQL创建的,然后通过
自动加载 对象类中的 __table_args__ = {'autoload': True}
语句。
我正在使用的SQLAlchemy调用对Item进行了几个过滤,以缩小范围,如下所示:
result = self.session.query(Item).filter(and_params).filter(or_params)
我当前的代码对此结果运行了一个按项目查询来获取它们的源代码,但由于可能会返回很多项目,因此代码需要相对较长的时间来获取我想要的所有内容。
我在这里要做的是以某种方式修改上述查询以获得所有 与Item关联的源,并添加其Source.name列表 和Source.special到我发现的每个项目。
更新1: 我已经使用其他帖子整理了一个mysql查询和一个sqlalchemy查询,这些帖子正确地获得了我想要的列表中的一个条目:
SELECT Item.iid, Item.name, GROUP_CONCAT(Source.sid) as source_sids,
GROUP_CONCAT(Source.name) as source_names,
GROUP_CONCAT(Source.special) as source_specials
FROM ItemSource
INNER JOIN Item
ON ItemSource.iid = Item.iid
INNER JOIN Source
ON ItemSource.sid = Source.sid
WHERE Item.iid = #
sqlalchemy是:
result = self.session.query(
Item,
func.group_concat(Source.sid).label('source_sids'),
func.group_concat(Source.name).label('source_names'),
func.group_concat(Source.special).label('source_specials')
).select_from(ItemSource)\
.join(Item, Item.iid == ItemSource.iid)\
.join(Source, Source.sid == ItemSource.sid)\
.filter(Item.iid == #)
但是,如果我添加一个或者是mysql语句或sqlalchemy调用(例如Item.iid == 5或Item.iid == 6),我只返回一个Item和source_sids,source_names和source_specials将以下所有条目都应该作为行添加到第一行中。
我如何制作它以便遍历这两个项目(或更多,如果使用不同的过滤器)?
更新2 :添加
解决.group_by(Item.iid)
到SQLAlchemy查询的末尾。
因此,SQLAlchemy查询将是:
result = self.session.query(
Item,
func.group_concat(Source.sid).label('source_sids'),
func.group_concat(Source.name).label('source_names'),
func.group_concat(Source.special).label('source_specials')
).select_from(ItemSource)\
.join(Item, Item.iid == ItemSource.iid)\
.join(Source, Source.sid == ItemSource.sid)\
.filter(Item.iid == #).group_by(Item.iid)