[英]Sqlalchemy query against list of dict
我正在尝试运行一个查询,根据dict列表筛选结果。
让我们更清楚......
我有一个表格标题,每个标题都有一个版本字段
class Heading(Base):
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False)
version = Column(Integer)
另一方面,我有一个看起来像这样的dict列表(Json格式化):
"headings": [
{
"id": 1,
"version": 1
},
{
"id": 2,
"version": 1
}
]
我想在Heading表上执行一个查询,该查询排除数据库中的版本等于(json)列表中的版本的行。
我尝试执行这样的事情:
res = Heading.query.filter(~Heading.id.in_([d['id'] for d in headings if d['version'] == Heading.version])).all()
数据库看起来像这样(Json再次格式化,对不起):
[
{
"id": 1,
"name": "Heading1",
"version": 2,
},
{
"id": 2,
"name": "Heading2",
"version": 1,
}
]
但它无论如何都会返回Heading2行。 基本上,我希望查询返回Json中未定义的所有行以及DB中具有较新版本的行。
我不知道我的问题是否足够明确。 也许这不是正确的方法,请告诉我
在此先感谢您的帮助
编辑:生成的原始SQL是这样的:
SELECT heading.id, heading.name, heading.version
FROM heading
WHERE heading.id = heading.id
所以sqlalchemy查询有一个明显的问题,但我无法弄清楚是什么......
我认为这是来自该部分
if d['version'] == Heading.version
但我不知道如何在查询的其他地方重新表述这种情况
正如你所怀疑的那样问题就在于
[... for ... if d['version'] == Heading.version]
虽然d['version'] == Heading.version
生成一个SQL表达式对象,然后Python使用其真值进行过滤:
In [9]: bool(headings[0]['version'] == Heading.version)
Out[9]: False
所以你的列表理解结果是一个空列表。 Heading.id
永远不会出现在空列表中,所以
~Heading.id.in_([])
将简单地评估为真:
In [10]: print(~Heading.id.in_([]))
1 = 1
鉴于您的数据库支持复合IN查询 ,解决方案是与(id,version)元组进行比较:
In [9]: from sqlalchemy import tuple_
In [10]: session.query(Heading).\
...: filter(~tuple_(Heading.id, Heading.version).in_(
...: [(d['id'], d['version']) for d in headings])).\
...: all()
Out[10]: [<__main__.Heading at 0x7f840cc8ae48>]
In [11]: _[0].name
Out[11]: 'Heading1'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.