Peewee - 我如何执行原始查询并将其映射到字典?

Peewee - How do i execute raw query and map it to the dictionary?

我一直在尝试执行原始查询并将其映射到字典。

虽然 execute_sql 没有 return 列名称,但它 return 是元组。

我使用原始查询,但它 returns None Abc 实例

class Abc(BaseModel):
    name = CharField()
    engine = CharField()

q = Abc.raw('show table status from ' + config.DB['name'])
print(list(q.execute()))

输出:

[<Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>, <Abc: None>]

sql

的结果

也许有更好的方法,但是使用 execute_sqlcursor.description 以及列名我可以为所有表创建带有字典的列表

import peewee

db = peewee.MySQLDatabase('my_database', user='my_user' password='my_password')

cursor = db.execute_sql('show table status from my_database')

all_tables = []

for row in cursor.fetchall():
    table = dict()

    for column, value in zip(cursor.description, row):
        column_name = column[0]
        print(column_name, '=', value)
        table[column_name] = value

    all_tables.append(table)

print(all_tables)    

我的数据库之一的结果:

[
 {'Name': 'alembic_version', 'Engine': 'InnoDB', 'Version': 10, 'Row_format': 'Dynamic', 'Rows': 0, 'Avg_row_length': 0, 'Data_length': 16384, 'Max_data_length': 0, 'Index_length': 0, 'Data_free': 0, 'Auto_increment': None, 'Create_time': datetime.datetime(2019, 4, 29, 17, 19), 'Update_time': None, 'Check_time': None, 'Collation': 'latin1_swedish_ci', 'Checksum': None, 'Create_options': '', 'Comment': ''}, 
 {'Name': 'users', 'Engine': 'InnoDB', 'Version': 10, 'Row_format': 'Dynamic', 'Rows': 0, 'Avg_row_length': 0, 'Data_length': 16384, 'Max_data_length': 0, 'Index_length': 65536, 'Data_free': 0, 'Auto_increment': 2, 'Create_time': datetime.datetime(2019, 4, 29, 17, 19), 'Update_time': None, 'Check_time': None, 'Collation': 'latin1_swedish_ci', 'Checksum': None, 'Create_options': '', 'Comment': ''}, 
 {'Name': 'woocommerce', 'Engine': 'InnoDB', 'Version': 10, 'Row_format': 'Dynamic', 'Rows': 0, 'Avg_row_length': 0, 'Data_length': 16384, 'Max_data_length': 0, 'Index_length': 16384, 'Data_free': 0, 'Auto_increment': 3, 'Create_time': datetime.datetime(2019, 4, 29, 17, 19), 'Update_time': None, 'Check_time': None, 'Collation': 'latin1_swedish_ci', 'Checksum': None, 'Create_options': '', 'Comment': ''}
]

编辑: 相同但具有列表理解

import peewee

db = peewee.MySQLDatabase('my_database', user='my_user' password='my_password')

cursor = db.execute_sql('show table status from my_database')

column_names = [x[0] for x in cursor.description]
all_tables = [dict(zip(column_names, row)) for row in cursor.fetchall()]

print(all_tables) 

在 peewee 中,Model.raw() 用于模型上的手动优化 select 语句,而不是一般的 select 语句 - 它 returns 模型实例从 select 结果中填写的声明字段。也就是说,如果 Wiget(Model) 的字段为 lengthwidthheight,则查询如:

wigets = Wiget.raw('select length from wigets where width > height')

...将 return 一个 Wiget 实例的可迭代 wigets 与 returned 值的字段 length,并且 widthheightNone 因为它们不在 select 离子列表中。 select * ... 将匹配 return 到 Wiget 字段的所有列并填写它们。

如果查询结果与架构模型不匹配(例如您的 show table status ... 示例),它仍然会 return 每行 Wiget 一个实例 returned,但无法将任何 returned 列与您定义的模型匹配,因此它们都保留为 None.

重要说明,SQL 不区分大小写,但 peewee 区分大小写,因此使用 SELECT LENGTH WHERE ...(或 select * 如果初始 create table 中的列进行查询语句是大写的)不会填充 length 字段,因为不同的大小写意味着它们不会匹配。也许将来会解决这个问题。