如何使用PeeWee将选择查询转换为pandas DataFrame

16

我使用PeeWee ORM进行以下查询:

query = DataModel.select()where(DataModel.field == "value")

有没有办法将query转换为pandas DataFrame而不必迭代所有值?我正在寻找一种更“Pythonic”的做法。

3个回答

35

假设 query 的类型是 peewee.SelectQuery,您可以执行以下操作:

df = pd.DataFrame(list(query.dicts()))

编辑:正如Nicola在下面指出的那样,现在您可以直接执行pd.DataFrame(query.dicts())


非常出色且操作起来像魔法一样!我不会告诉你我花了多长时间才明白它,太尴尬了。哈哈 - MikeyE
1
由于某些原因,如果有一个列的名称与表名相同,list(query.dicts()) 将会失败... 有人遇到过同样的问题吗? - toto_tico
不要使用list(),正确的代码是:pd.DataFrame(query.dicts()) - Nicola

6

如果有人发现这个有用的话,我正在搜索相同的转换,但在Python 3中。受@toto_tico之前的答案的启发,我想到了这个:

import pandas
import peewee


def data_frame_from_peewee_query(query: peewee.Query) -> pandas.DataFrame:
    connection = query._database.connection()  # noqa
    sql, params = query.sql()
    return pandas.read_sql_query(sql, connection, params=params)

使用 Python 3.9.6pandas==1.3.2peewee==3.14.4,使用 peewee.SqliteDatabase 进行检查。


1
非常感谢您写下这篇文章——这是100%正确的答案。 - zachwill

4
以下是一种更高效的方法,因为它避免了创建列表然后将其传递给pandas数据帧。它还有一个附加好处,即保留列的顺序:
df = pd.read_sql(query.sql()[0], database.connection())

您需要直接访问peewee 数据库,例如,在快速入门教程中对应的内容为:

db = SqliteDatabase('people.db')

当然,您也可以创建自己的数据库连接。
不足之处:如果两个表中有重复列,例如“id”列会出现两次,请务必在继续之前进行更正。
如果您使用的是peewee代理,则...
import peewee as pw; 
database_proxy = pw.Proxy()

那么连接就在这里:

database_proxy.obj.connection()

1
你如何处理 query.sql()[0] 返回的字符串中包含 %s 占位符的情况? - LivingSilver94
我需要查看您的确切查询,但通常情况下,这可能意味着存在格式化字符串Python语法,请参考此链接 - toto_tico
1
@LivingSilver94 这不是一个完整的解决方案,但对于Postgres来说,获取光标并使用mogrify是可行的:cursor = db.cursor() 然后 pd.read_sql(cursor.mogrify(*query.sql()), ...) - user5915738

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接