Open ghost opened 2 years ago
Thanks for pointing this out. I hadn't run into this issue.
If you don't have permission to read ir.model.access
, you need to pass the list of fields you want to read to search_read
. Instead of
= search_read("res.partner", { {"is_company", "=", true} }, [order="customer_rank"])
you should run
= search_read("res.partner", { {"is_company", "=", true} }, [order="customer_rank", fields={"name", "email", "phone"}])
If you have a one2many field on a model, that field isn't actually stored on that model's table, it is instead stored on the referenced model's table as many2one fields. This means that if you want to read a one2many field, you need permission to read the referenced model.
If you run
= search_read("res.partner", { }, [fields={"invoice_ids"}])
you need to have permission to read account.move
as well as res.partner
.
The behaviour of Odoo's search_read
is such that if you don't specify fields
it queries all the model's fields, but that might include one2many fields which reference models the user isn't able to read, resulting in an AccessError
.
I want this connector to eventually be usable by people with limited or no knowledge of Odoo development. They'd just select the tables they want to query from the "Get data" dialog and use the PowerBI UI or PowerQuery functions to manipulate the data. The connector would determine the most efficient search_read
call possible such that the server does the most amount of work and transmits the least amount of data possible (query folding).
For that to be achievable, when you call search_read
without passing the fields
parameter, the connector first checks ir.model.access
and excludes from the query any one2many fields which reference models you can't read. Instead of returning an error, it will return all the columns you have permission to read.
I'll add something to the readme and to the search_read
docstring.
Also, if anyone knows of a better way of checking if a one2many field is readable (maybe even including ir.rule
checks) without requiring the installation of a custom module on the server, I'm all ears.
Thanks @tmijail for this helpful and detailed reply. Makes a lot of sense. If I have any ideas that could help, will let you know.
I've found that if you run the search_read method, unless your user account has Administrator Settings permission an error occurs as below.
Odoo Server Error: You are not allowed to access 'Model Access' (ir.model.access) records.
This operation is allowed for the following groups:
Contact your administrator to request access if necessary. Details: Traceback (most recent call last): File "/data/build/odoo/odoo/http.py", line 1452, in _dispatch_nodb result = request.dispatch() File "/data/build/odoo/odoo/http.py", line 684, in dispatch result = self._call_function(self.params) File "/data/build/odoo/odoo/http.py", line 361, in _call_function return self.endpoint(*args, *kwargs) File "/data/build/odoo/odoo/http.py", line 913, in call return self.method(args, kw) File "/data/build/odoo/odoo/http.py", line 532, in response_wrap response = f(*args, kw) File "/data/build/odoo/odoo/addons/base/controllers/rpc.py", line 96, in jsonrpc return dispatch_rpc(service, method, args) File "/data/build/odoo/odoo/http.py", line 141, in dispatch_rpc result = dispatch(method, params) File "/data/build/odoo/odoo/service/model.py", line 41, in dispatch res = fn(db, uid, params) File "/data/build/odoo/odoo/service/model.py", line 168, in execute_kw return execute(db, uid, obj, method, args, kw or {}) File "/data/build/odoo/odoo/service/model.py", line 94, in wrapper return f(dbname, *args, kwargs) File "/data/build/odoo/odoo/service/model.py", line 175, in execute res = execute_cr(cr, uid, obj, method, *args, *kw) File "/data/build/odoo/odoo/service/model.py", line 159, in execute_cr result = odoo.api.call_kw(recs, method, args, kw) File "/data/build/odoo/odoo/api.py", line 395, in call_kw result = _call_kw_model(method, model, args, kwargs) File "/data/build/odoo/odoo/api.py", line 368, in _call_kw_model result = method(recs, args, kwargs) File "/data/build/odoo/odoo/models.py", line 2254, in read_group result = self._read_group_raw(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy) File "/data/build/odoo/odoo/models.py", line 2276, in _read_group_raw self.check_access_rights('read') File "/data/build/odoo/odoo/models.py", line 3332, in check_access_rights return self.env['ir.model.access'].check(self._name, operation, raise_exception) File "", line 2, in check
File "/data/build/odoo/odoo/tools/cache.py", line 90, in lookup
value = d[key] = self.method(*args, **kwargs)
File "/data/build/odoo/odoo/addons/base/models/ir_model.py", line 1805, in check
raise AccessError(msg)
Exception
The above exception was the direct cause of the following exception:
Traceback (most recent call last): File "/data/build/odoo/odoo/http.py", line 640, in _handle_exception return super(JsonRequest, self)._handle_exception(exception) File "/data/build/odoo/odoo/http.py", line 316, in _handle_exception raise exception.with_traceback(None) from new_cause odoo.exceptions.AccessError: You are not allowed to access 'Model Access' (ir.model.access) records.
This operation is allowed for the following groups:
Contact your administrator to request access if necessary.