Odoo ORM 支援某些 SQL 功能,如視圖 (Views)、索引 (Indexes)、事務 (Transactions)、資料完整性 (Data Integrity)、資料安全性 (Data Security),以及某些層次的子查詢 (Subqueries)。這些功能在 Odoo 中的實現方式略有不同,以下是詳細的介紹:
功能 | Odoo ORM | SQL |
---|---|---|
View (視圖) | 透過 compute fields 或模型模擬視圖 |
SQL 原生支持 View |
Data Integrity (資料完整性) | 透過 _sql_constraints 和欄位屬性 |
透過約束和索引保障資料完整性 |
Data Security (資料安全性) | 使用存取權限和記錄規則進行控管 | 使用 SQL 用戶權限和 GRANT/REVOKE |
Subqueries (子查詢) | 限制於 ORM 層次,複雜查詢需撰寫 SQL | SQL 支援任意複雜度的子查詢 |
Odoo ORM 中並沒有直接支持 SQL 視圖的概念。然而,可以透過自訂模型來模擬視圖的效果。Odoo 中可以使用 @api.depends 或計算欄位 (compute fields) 來動態生成計算結果,類似於視圖的概念。
class ResPartnerInvoicing(models.Model):
_name = 'res.partner.invoicing'
_description = 'Invoicing Report'
partner_id = fields.Many2one('res.partner')
total_invoiced = fields.Float(compute='_compute_total_invoiced')
@api.depends('partner_id')
def _compute_total_invoiced(self):
for record in self:
record.total_invoiced = sum(record.partner_id.invoice_ids.mapped('amount_total'))
Odoo 使用 PostgreSQL 作為資料庫,並內建支援 SQL 事務。ORM 操作是在事務內進行的,這意味著當操作失敗時,可以自動回滾。在 Odoo 中,每個請求 (request) 都是在一個事務中執行的。
手動控制事務: Odoo 自動處理事務,但你也可以通過 cr (cursor) 來手動控制事務,例如:
from odoo import api, SUPERUSER_ID
@api.model
def process_transaction(self):
cr = self.env.cr
try:
# 一些 ORM 操作
cr.commit() # 提交事務
except Exception:
cr.rollback() # 回滾事務
SQL 約束:
class ResPartner(models.Model):
_inherit = 'res.partner'
_sql_constraints = [
('check_credit_limit', 'CHECK(credit_limit >= 0)', 'Credit limit must be positive')
]
此外,Odoo 還支援 required、unique 等欄位屬性,來加強資料完整性。
存取權限 (Access Control): 存取權限允許設定不同的模型操作權限,例如 read、write、create 和 unlink,分別對應查詢、更新、創建和刪除操作。
記錄規則 (Record Rules): 記錄規則可設定細粒度的資料訪問權限,基於使用者或群組的不同,來動態決定誰可以存取哪些記錄。
<record id="partner_rule" model="ir.rule">
<field name="name">Partner rule</field>
<field name="model_id" ref="model_res_partner"/>
<field name="domain_force">[('user_id', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('group_user'))]"/>
</record>
ORM 層級的查詢: Odoo 的查詢方法能模擬一些簡單的子查詢,像是用 search 找到一組記錄,然後基於這些記錄進行進一步的查詢。
查詢 John Doe 的所有銷售訂單
partner = env['res.partner'].search([('name', '=', 'John Doe')])
orders = env['sale.order'].search([('partner_id', '=', partner.id)])
原生 SQL 查詢: 如果需要更複雜的子查詢,可以直接撰寫 SQL 語句,並使用 env.cr 來執行。
self.env.cr.execute("""
SELECT * FROM sale_order
WHERE partner_id IN (SELECT id FROM res_partner WHERE name = 'John Doe')
""")
功能 | Odoo ORM | SQL |
---|---|---|
View (視圖) | 透過 compute fields 或模型模擬視圖 |
SQL 原生支持 View |
Data Integrity (資料完整性) | 透過 _sql_constraints 和欄位屬性 |
透過約束和索引保障資料完整性 |
Data Security (資料安全性) | 使用存取權限和記錄規則進行控管 | 使用 SQL 用戶權限和 GRANT/REVOKE |
Subqueries (子查詢) | 限制於 ORM 層次,複雜查詢需撰寫 SQL | SQL 支援任意複雜度的子查詢 |
Odoo ORM 支援許多 SQL 的核心功能,並且透過抽象層的優勢,讓開發者能以更簡潔的方式操作資料庫。然而,對於需要複雜查詢、視圖等功能的場合,可能需要手動撰寫 SQL 查詢來補充 ORM 的功能。這種靈活性讓 Odoo 成為一個強大且易於擴展的 ERP 平台,能夠滿足大多數商業應用中的資料庫需求。