1. 简介
在 Odoo 中,执行 SQL 查询后可以使用 fetchall()
或 dictfetchall()
方法来获取查询结果。fetchall()
返回的是一个包含元组的列表,而 dictfetchall()
返回的是一个包含字典的列表。两者的主要区别在于数据访问的方式:fetchall()
通过索引访问数据,而 dictfetchall()
通过字段名称访问数据。
2. fetchall()
示例
首先,让我们看一下使用 fetchall()
的示例。
from odoo import models, api
class PartnerExample(models.Model):
_inherit = 'res.partner'
@api.model
def get_partner_info(self):
cr = self._cr # 获取数据库游标
cr.execute("""
SELECT id, name, email
FROM res_partner
WHERE customer_rank > 0
""")
results = cr.fetchall() # 获取查询结果
# 处理结果
for row in results:
partner_id = row[0] # 通过索引访问
partner_name = row[1]
partner_email = row[2]
# 打印结果
print(f"ID: {partner_id}, Name: {partner_name}, Email: {partner_email}")
return results
运行结果:
假设 res_partner
表中的数据如下:
id | name | email | customer_rank |
1 | John Doe | 1 | |
2 | Jane Smith | 2 |
执行该方法后,将输出:
ID: 1, Name: John Doe, Email: [email protected]
ID: 2, Name: Jane Smith, Email: [email protected]
优点和缺点:
- 优点:
- 更加简单直接,适合小规模数据处理。
- 缺点:
- 如果列顺序改变,代码可能会出错。
- 可读性较差,尤其是当列数较多时。
3. dictfetchall()
示例
看一下使用 dictfetchall()
的示例。
from odoo import models, api
class PartnerExample(models.Model):
_inherit = 'res.partner'
@api.model
def get_partner_info(self):
cr = self._cr # 获取数据库游标
cr.execute("""
SELECT id, name, email
FROM res_partner
WHERE customer_rank > 0
""")
results = cr.dictfetchall() # 使用dictfetchall获取结果
# 处理结果
for row in results:
partner_id = row['id'] # 通过字段名称访问
partner_name = row['name']
partner_email = row['email']
# 打印结果
print(f"ID: {partner_id}, Name: {partner_name}, Email: {partner_email}")
return results
运行结果:
数据表相同,执行该方法后输出与 fetchall()
示例相同:
ID: 1, Name: John Doe, Email: [email protected]
ID: 2, Name: Jane Smith, Email: [email protected]
优点和缺点:
- 优点:
- 使用字段名称访问数据,代码可读性更高。
- 列顺序改变不会影响代码。
- 缺点:
- 相比
fetchall()
,可能略微增加了处理时间和内存占用。
4. 比较总结
fetchall()
:返回元组列表,数据访问通过索引完成。适合简单或性能要求较高的场景,但代码可读性较差且容易出错。dictfetchall()
:返回字典列表,数据访问通过字段名称完成。代码更具可读性和维护性,适合处理复杂数据或长久维护的系统。
5. 实际应用场景
- 使用
fetchall()
的场景:当你只处理少量列且数据结构很稳定时,可以选择fetchall()
,以稍微提升性能。 - 使用
dictfetchall()
的场景:当你需要处理多列数据,并且需要代码的可读性和维护性,特别是在团队协作或长时间维护的项目中,dictfetchall()
是更好的选择。