2015-01-20 15 views
1

請幫我理解peewee 2.4.5在與MySQL 5.5交談時的行爲。我正在運行一個簡單的查詢來計算與父級關聯的子級;在這種情況下,文件在一個路徑。作爲普通的SQL它歸結爲:Peewee ORM查詢結果fn.COUNT是類型unicode,不是整數

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完成的結果是整型。這是一個功能嗎?我在這裏犯了一個愚蠢的python錯誤嗎?提前致謝。

''' 
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() 

回答

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)) 
+0

好fn.COUNT(CharField)產生被強制轉換爲字符串的結果,我可以停止.coerce(假)的脅迫。現在我明白髮生了什麼,我改變了代碼來計算Doc.path字段,它是整數,結果是整數。謝謝。 – chrisinmtown 2015-01-21 13:19:30

+0

您可能會將此標記爲正確答案,以便將來任何人都能看到如何解決此問題。 – coleifer 2015-01-21 17:05:41

+0

是的!完成!感謝您的推動。 – chrisinmtown 2015-01-21 18:21:10

相關問題