Enable Dark Mode!
By: Amal Prasad

Odoo ORM Environment & Configuration

Odoo 14

Odoo is a vast ERP stage with high potential. With every new version of Odoo, it is potential and options for customization are increasing.
In this blog, we will be discussing the Odoo ORM Environment.
Before moving ahead into the blog let me give you a quick overview of ORM. ORM(Object Relational Mapping) is a concept that acts as a link between the programming language and the odoo database. We don’t have to write SQL queries explicitly in Object Relational Mapping or the ORM. Users can use OOP Concepts like classes and objects to communicate with Odoo databases.
The ORM Environment is the most important part of ORM. It mainly stores various context data used by the Odoo ORM such as:
* Database Cursor - To database queries.
* Current User - To check access rights.
* Current Context -  Used to store arbitrary metadata.
* Caches.
All the recordset in Odoo have an environment, it is immutable and it can be accessed by “env”. This ”env” is used to give to:
* user - the current user
* cr - the cursor
* su - the superuser flag
* context - or the context
>>> records.env
<Environment object ...>
>>> records.env.user
>>> records.env.cr
<Cursor object ...)
In ORM to create a recordset from another recordset the environment of the recordset where the record needs to be created will be inherited, then it can be used to create a dataset inside it.
>>> self.env['res.partner']
>>> self.env['res.partner'].search([['is_company', '=', True], ['customer', '=', True]])
res.partner(7, 18, 12, 14, 17, 19, 8, 31, 26, 16, 13, 20, 30, 22, 29, 15, 23, 28, 74)
Now let's look at some predefined functions, which can be accessed using “env”
* Environment.ref(xml_id, raise_if_not_found=True) - It will return the record corresponding to the xml_id. 
  Example - self.env.ref('mail.mt_comment')
* Environment.lang - It will return the current language code. Its return type: str.
   Example - self.env.lang
* Environment.user - This returns the currently logged-in user (as an instance of the environment). The return type is res_users.
   Example - self.env.user
* Environment.company - This returns the currently active company (as an instance of the environment). If it is not specified in the context of instance (allowed_company_ids), then what it will do is that it returns the currently logged-in user's main company as the current active company. The return type of this is res.company, also if it is in sudo mode, a logged-in user can access any company, even if the user is not allowed in that company. It raises Access Error on invalid or unauthorized allowed_company_ids context key content.
  Example - self.user.company_id
* Environment.companies - This returns a recordset of all the companies enabled to the user. If it is not specified in the context of instance (allowed_company_ids), then what it will do is that it returns the currently logged-in user's main company as the currently active company. And also it will raise an Access Error for the invalid or an unauthorized allowed_company_ids as context key of the content.
  Example - self.user.company_ids
Altering the Environment
* Model.with_context( [context] [, **overrides] ) - 
The current recordset in a new version will be returned to you which will be attached to the instance extended context. The extended context will either provide the “context” in which the overrides are merged to or it will provide the “current context” in which overrides are merged.
 Example - 
# current context is {'key1': True}
r2 = records.with_context({}, key2=True)
# -> r2._context is {'key2': True}
r2 = records.with_context(key2=True)
# -> r2._context is {'key1': True, 'key2': True}
* Model.with_user(user) - The recordset in a new version will be returned with the respective used assigned as a non-super user, unless the given user is the superuser.
 Example - self.env['res.config.settings'].with_user(self.user.id), It will return a new version of the current record set with the current user id.
* Model.with_company(res_company) - Consider the case that a user has logged in to two companies RED and GREEN with RED as the main company and he needs to create a record for the second company GREEN, the values for the company-dependent fields will be that of company RED.
 To get the dependent fields set values of a company from another company, we need to ensure that the current company we are using is correct. This can be done with the help of with_company(), this will update the current company value.
* Model.with_env(env) - This returns a new version recordset currently attached to the provided environment.
  Actions = self. with_context(active_test=True).
  sudo() .search(domain)
  return actions.with_env(self.env)
* Model.sudo([flag=True]) -  This returns a new version recordset with enabled or disabled superuser mode, depending on the value of the flag. Furthermore, the superuser mode which has been defined bypasses and overcomes the access rights checks without any hurdles as it is provided with the ultimate operations capability and does not change the current login user.
  Example -
The thing to keep in mind is that sudo will allow data access out of the boundaries of record rules set for a model, thereby the record which should be kept isolated will be mixed up, for example in a multi-company environment, data of different companies should not be mixed up.
SQL Execution
The ‘cr’ in the Odoo ORM environment stands for ‘cursor', which is used for transactions of the current database. Moreover, it also allows the execution of SQL queries directly in the database, either for queries that are difficult to express using the ORM (e.g. complex joins) or for performance reasons.
self.env.cr.execute("some_sql", params)
It is necessary to invalidate and clear cache when using SQL commands to CREATE, UPDATE or DELETE this is because the model uses the same cursor but the environment holds different caches. 
Moreover, it can be performed using the invalidate_cache() method.
* Model.invalidate_cache(fnames=None, ids=None) - It is used to Invalidate the record caches after some modifications have been done to some records that are currently in cache. The whole cache will be cleared if both fnames and ids are None.
fnames – the list of modified fields, or None for all fields.
ids – the list of modified record ids or None for all
Example -
We can either use queries or ORM utilities, one thing we have to make sure is that when using queries, your queries are free of errors and bugs when using user input. Instead, it is recommended to use ORM utilities. This is because the security rules of Odoo and ORM may be bypassed when executing raw SQL queries.

If you need any assistance in odoo, we are online, please chat with us.


Leave a comment



Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635



Cybrosys Limited
Alpha House,
100 Borough High Street, London,
SE1 1LB, United Kingdom



Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.



Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message