Peewee ORM查询结果fn.COUNT是类型unicode,而不是整数

时间:2015-01-20 20:43:46

标签: python mysql orm peewee

在与MySQL 5.5交谈时,请帮助我理解peewee 2.4.5的行为。我正在运行一个简单的查询来计算与父母相关的孩子;在这种情况下,文件在路径上。作为普通的SQL,它归结为:

select p.name, count(d.file) as child_count 
from path as p, doc as d 
where p.id = d.path_id 
group by p.name

Peewee代码使用fn.COUNT功能,请参阅下面的自包含示例。结果很好,并且我希望得到结果,但有一个例外:查询结果对象属性“child_count”的类型是unicode而不是整数。在这个小例子中有1行,我得到一个字符串(基本上)'1'而不是数字1。

我很困惑因为在fn.COUNT的其他查询中,结果是整数类型。这是一个功能吗?我在这里犯了一个愚蠢的蟒蛇错误吗?提前谢谢。

'''
Example of accessing MySQL from Python using Peewee.
Developed with peewee 2.4.5, pymysql 0.6.3, MySql 5.5
'''
from __future__ import print_function
from peewee import MySQLDatabase, Model, CharField, ForeignKeyField, fn

db = MySQLDatabase(database="test", host="localhost", user="mumble", password="foo")

class MySQLModel(Model):
    '''
    Base class to associate the database object
    '''
    class Meta:
        database = db

class Path(MySQLModel):
    # peewee adds primary key field 'id'
    name = CharField()

class Doc(MySQLModel):
    # peewee adds primary key field 'id'
    path = ForeignKeyField(Path)
    file = CharField()

def main():
    db.connect()
    db.create_tables([Path, Doc], True)
    newpath = Path(name='ab/23')
    newpath.save()
    newdoc1 = Doc(path=newpath.id, file='file1.txt')
    newdoc1.save()
    newdoc2 = Doc(path=newpath.id, file='file2.txt')
    newdoc2.save()
    for row in Path.select():
        print("Path: id=%d, name=%s" % (row.id, row.name))
    for row in Doc.select():
        print("Doc: id=%d, file=%s" % (row.id, row.file))
    # query in plain old SQL:
    # select p.name, count(d.file) from path as p, doc as d where p.id = d.path_id group by p.name
    path_doc_result = (Path
        .select(Path.name, fn.COUNT(Doc.file).alias('child_count'))
        .join(Doc, on=(Path.id == Doc.path)) 
        .group_by(Path.name))
    path_doc_count = len(list(path_doc_result))
    print("Path-doc parent-child result count is %d" % path_doc_count)
    if path_doc_count == 0:
        print("Programmer error, no results!")
    else:
        # get the first one
        d_row = path_doc_result[0]
        #### Why is the child_count attribute not integer? ###
        print("Type of child_count attribute is %s" % type(d_row.child_count))
        print("Path-Doc result: name=%s child_count=%d" % (d_row.name, int(d_row.child_count)))

    newdoc1.delete_instance()
    newdoc2.delete_instance()
    newpath.delete_instance()
    # order matters for foreign keys!
    db.drop_table(Doc)
    db.drop_table(Path)
    db.close()

if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:2)

Peewee函数查看第一个参数的类型,并尝试将返回值强制转换为该类型。这在大多数情况下都有意义,但我可以看到它为什么会在这里引起问题。

要解决此问题,请致电fn.COUNT(Doc.file).coerce(False).alias('child_count')

path_doc_result = (Path
    .select(Path.name, fn.COUNT(Doc.file).coerce(False).alias('child_count'))
    .join(Doc, on=(Path.id == Doc.path)) 
    .group_by(Path.name))