@@ -712,6 +712,7 @@ Useful environment methods
712712.. automethod :: Environment.is_admin
713713.. automethod :: Environment.is_system
714714.. automethod :: Environment.execute_query
715+ :noindex:
715716
716717Altering the environment
717718------------------------
@@ -749,9 +750,33 @@ The recommended way to build SQL queries is to use the wrapper object
749750
750751.. autoclass :: odoo.tools.SQL
751752
752- .. automethod :: SQL.join
753753 .. automethod :: SQL.identifier
754754
755+ The :func: `~odoo.api.Environment.execute_query ` allows to flush (see later),
756+ execute and fetch results at once.
757+ To translate model fields into SQL, and build queries, a useful abstraction
758+ is provided in
759+
760+ .. autoclass :: odoo.models.Query
761+
762+ .. automethod :: Query.select
763+ .. automethod :: Query.subselect
764+ .. automethod :: Query.is_empty
765+ .. automethod :: Query.get_result_ids
766+ .. autoproperty :: Query.table
767+
768+ .. example ::
769+
770+ .. code-block :: python
771+
772+ query = Query(self .env[' model' ])
773+ query.add_where(SQL(" %s > %s " , query.table.some_field, ' test' ))
774+ query.select()
775+ # SELECT model.id
776+ # FROM model
777+ # WHERE model.some_field > 'test'
778+
779+
755780 One important thing to know about models is that they don't necessarily perform
756781database updates right away. Indeed, for performance reasons, the framework
757782delays the recomputation of fields after modifying records. And some database
@@ -781,6 +806,11 @@ when flushing.
781806
782807.. automethod :: Model.flush_recordset
783808
809+ .. automethod :: odoo.api.Environment.execute_query
810+
811+ When using the Query builder and ``execute_query ``, model flushes are done based
812+ on the metadata in the ``SQL ``.
813+
784814Because models use the same cursor and the :class: `~odoo.api.Environment `
785815holds various caches, these caches must be invalidated when *altering * the
786816database in raw SQL, or further uses of models may become incoherent. It is
@@ -799,6 +829,13 @@ SQL, but not ``SELECT`` (which simply reads the database).
799829 # invalidate 'state' from the cache
800830 self .env[' model' ].invalidate_model([' state' ])
801831
832+ .. code-block :: python
833+
834+ # get name and country name for all records, flushing and joins are
835+ # done automatically
836+ query = Query(self .env[' model' ])
837+ self .env.execute_query(query.select(SQL(query.table.name, query.table.country_id.name)))
838+
802839 Just like flushing, one can invalidate either the whole cache, the cache of all
803840the records of a model, or the cache of specific records. One can even
804841invalidate specific fields on some records or all records of a model. As the
0 commit comments