Python Peewee group_concat/案例问题

Python Peewee group_concat/案例问题,python,peewee,Python,Peewee,我正在尝试使用peewee来获取和格式化来自sqlite数据库的一些数据,使用GROUP_CONCAT和Case。但我面临着这些功能的问题 首先,让我们从我想要实现的目标开始: 我简化了我的表结构,以便更好地指出问题:1个简单的表有两列:name(Char),is_controlled(Boolean)。 此SQL请求将计算所需的结果: SELECT SUM(is_controlled), GROUP_CONCAT(CASE WHEN is_controlled = 1 TH

我正在尝试使用peewee来获取和格式化来自sqlite数据库的一些数据,使用GROUP_CONCAT和Case。但我面临着这些功能的问题


首先,让我们从我想要实现的目标开始:

我简化了我的表结构,以便更好地指出问题:1个简单的表有两列:name(Char),is_controlled(Boolean)。 此SQL请求将计算所需的结果:

SELECT 
    SUM(is_controlled),
    GROUP_CONCAT(CASE WHEN is_controlled = 1 THEN name ELSE NULL END, ':') as controlled,
    GROUP_CONCAT(CASE WHEN is_controlled = 0 THEN name ELSE NULL END, ':') as not_controlled
FROM component;
输出(这是我希望peewee的输出):


下面是一个脚本,用于测试我的问题:

from peewee import *

db = SqliteDatabase('test.db')


class Component(Model):
name = CharField()
is_controlled = BooleanField()

class Meta:
database = db


raw_data = [
    {'name': 'comp1', 'is_controlled': True},
    {'name': 'comp2', 'is_controlled': False},
    {'name': 'comp3', 'is_controlled': True},
]

db.connect()

# Populate database
db.create_tables([Component])
for item in raw_data:
    Component.get_or_create(**item)

res = Component.select(
    fn.Sum(Component.is_controlled).alias('controlled_count'),
    fn.GROUP_CONCAT(Case(None, [((Component.is_controlled == True), Component.name)], None), ':').alias('controlled'),
    fn.GROUP_CONCAT(Case(None, [((Component.is_controlled == False), Component.name)], None), ':').alias('not_controlled')
)


print res[0].controlled_count
print res[0].controlled
print res[0].not_controlled

db.close()
如您所见,数据结构很简单(我在示例中最大限度地简化了)。输出为:

2
:comp3:
:
我检查了peewee(使用res.SQL())生成的SQL查询,结果如下:

sql = 'SELECT Sum("t1"."is_controlled") AS "controlled_count", GROUP_CONCAT(CASE WHEN ("t1"."is_controlled" = ?) THEN ? END, "t1"."name") AS "controlled", GROUP_CONCAT(CASE WHEN ("t1"."is_controlled" = ?) THEN ? END, "t1"."name") AS "not_controlled" FROM "component" AS "t1"'

params = [True, ':', False, ':']
我们可以看到peewee生成的SQL请求中缺少ELSE NULL部分。我尝试过几件事,比如调整Case函数的参数,但我无法让它正常工作

如何正确使用peewee以获得与使用SQL相同的结果


(我正在使用python 2.7.15和peewee 3.6.4 ans sqlite 3.19.4)

函数的签名提供了一个线索:

def Case(predicate, expression_tuples, default=None):
在代码内部,它检查:

if default is not None:
    clauses.extend((SQL('ELSE'), default))
因此,当您传递
None
时,它与“空/未指定”情况无法区分,Peewee会忽略它


作为一种解决方法,您可以将
SQL('NULL')
指定为默认值。或者您可以使用一个空字符串,尽管我不确定您是否依赖于带有null的group concat的某些行为,因此这可能不起作用?

非常感谢您的快速响应(通常也感谢peewee!)。这是可行的,我在我的示例中犯了一个错误(我颠倒了一些参数),这是我想要的:
fn.GROUP_CONCAT(Case(None),[((Component.is_controlled==True),Component.name)],SQL('NULL'),':')
if default is not None:
    clauses.extend((SQL('ELSE'), default))