SlideShare a Scribd company logo
2019
Odoo Experience
New Framework / ORM
Fabien Pinckaers • Founder
Odoo 13: the biggest
ORM refactoring
since OpenERP 8
Odoo 13: the biggest
ORM refactoring
since OpenERP 8
In-Memory ORM
Performance: Time
4.5x faster, on average
Performance: SQL
4x less SQL queries, on average → faster perf on larger DB
Perf Demo
Evolution of The ORM for
Perf Improvements
Single Cache
Instead of one cache per env / context
➔ Stored fields have a single value
➔ Computed, non-stored fields’ value
depends on specific keywords in the
context
➔ ex: translatable, properties
v12 cache structure:
➔ {env: {field: {id: value}}}
v13 cache:
➔ {field: {id: value}}
v13 cache, @depends_context fields:
➔ {field: {id: {context_keys: value}}}
# Odoo 12
self.field # SELECT
r = self.with_context(key=val) # new cache
r.field # SELECT
self.sudo().field # new cache + SELECT
# Odoo 13
self.field # SELECT
r = self.with_context(key=val)
r.field
self.sudo().field
Prefer In-Memory updates
Instead of SQL queries
➔ put in cache, instead of writing in DB
➔ env.all.towrite contains values to UPDATE
➔ nearly never invalidate cache, update it
instead (e.g. changing a many2one, will
update cached values of its one2many)
➔ flush([fields]):
◆ write in DB (minimize updates)
◆ recompute optional fields
◆ called at end of rpc
➔ create() does INSERT directly
# Odoo 12
self.name = 'test' # UPDATE + invalid cache
self.name = 'test2' # UPDATE + invalid cache
self.name # SELECT
# Odoo 13
self.name = 'test' # put in cache
self.name = 'test2' # put in cache
self.name # get from cache
self.flush() # UPDATE
Dependencies In-Memory
class order(Model):
discount = Float()
line_ids = One2many('order_id')
class order_line(Model):
order_id = Many2one('order')
price = Float()
subtotal = Float(compute="get_total")
@api.depends('price','order_id.discount')
def get_total(self):
self.subtotal = self.price * self.order_id.discount
# Odoo 12
for order in self:
order.discount = 10.0 # SELECT id WHERE order_id
# UPDATE order
# Odoo 13
for order in self:
order.discount = 10.0 # no SQL
self.flush() # UPDATE order WHERE id IN ()
Whenever possible
➔ instead of SQL query, get inverse field, ex:
to evaluate @depends(‘order_id’), check
value of line_ids in the cache
➔ usually avoids a SELECT as the
implementation of the compute will read the
same object
➔ if no inverse field, fall back to SQL query
(e.g. many2one without a one2many)
➔ when create(), set one2many to []
Delay computed field
As late as possible
➔ compute fields:
◆ only if you read it
◆ or if you need to flush in the DB
➔ as the old value stays in memory, we can
optimize to not recompute if the value do
not change
# odoo 12
for line in order:
line.product_qty = 1 # mark to recompute
# compute l.subtotal, o.total
line.discount = 10 # mark to recompute
# compute l.subtotal, o.total
line.price = 100 # mark to recompute
# compute l.subtotal, o.total
# odoo 13
for line in order:
line.product_qty = 1 # mark to recompute
line.discount = 10 # mark to recompute
line.price = 100 # mark to recompute
self.flush() # recompute all lines & orders
Delay SQL updates
As late as possible
➔ save all changes in a self.env.all.towrite
➔ optimize updates, to minimize queries:
update several records at once
update several fields at once
# odoo 12
for line in order:
line.state = 'draft' # UPDATE ... WHERE ID = x
# odoo 13
for line in order:
line.state = 'draft'
self.flush() # UPDATE ... WHERE ID IN (...)
Optimize dependency tree
to reduce python & sql computations
v12: recursive dependencies
change order.discount
→ order_line.subtotal depends on it
→ to recompute subtotal
→ order_id.total depends on it (for each line)
→ to recompute order.total
v13: optimized dependency trees
change order.discount
→ to recompute total
→ order_line.subtotal depends on it
→ to recompute order_line.subtotal
class order(Model):
discount = Float()
line_ids = One2many('order_id')
class order_line(Model):
order_id = Many2one('order')
price = Float()
subtotal = Float(compute="get_total")
@api.depends('price','order_id.discount')
def get_total(self):
self.subtotal = self.price * self.order_id.discount
# Impact of:
order.discount = 1
browse() optimization
Avoid multiple format conversion
➔ cache format similar to DB to avoid
conversion:
None instead of False
4 instead of (4,) for many2one
➔ don’t convert to read() format, for browse
records
# Odoo 12
self.field
→ prefetch
→ read
→ _read
SQL query
convert_to_cache
put in cache
→ get from cache (convert_to_record)
→ convert_to_read
# Odoo 13
self.field
→ prefetch
_read
SQL query
put in cache
And a lot of code cleanup,
and Python optimization.
Demonstration
speed + SQL
on the way to deprecate
onchange()
Who can tell what
onchange_partner_id()
does on a sale.order?
(not me)
How is the sale.order
pricelist_id field computed?
And the delivery address?
(much easier to express)
Compute vs onchange
Computed Fields
✓ Work in Python module & JS client
✓ Clean dependency graph
✓ Express a business logic
✓ Separation of business concepts
⛌ Field readonly (but can be inverted)
onchange() method
⛌ Only work in JS client
⛌ No dependency graph: recursion
⛌ interface logic, not business logic
⛌ Business concepts aggregated
✓ Allow to edit the field
The new framework supports fields with:
compute=”...”, readonly=False
compute method might not set a value
Compute vs onchange
Example: Definition
onchange() → compute()
# Odoo 12
pricelist_id = fields.Many2one()
delivery_id = fields.Many2one()
@api.onchange('partner_id')
def onchange_partner_id(self):
for order in self:
order.pricelist_id = order.partner_id.pricelist_id
order.delivery_id = order.partner_id.pricelist_id
# Odoo 13
pricelist_id = fields.Many2one(compute="comp_pl_id",
readonly=False)
delivery_id = fields.Many2one(compute="comp_delivery_id")
@api.depends('partner_id')
def compute_pricelist_id(self):
for order in self:
self.pricelist_id = order.partner_id.pricelist_id
@api.depends('partner_id')
def compute_delivery_id(self):
for order in self:
self.delivery_id = order.partner_id.pricelist_id
➔ reverse the definition: instead of telling
what field is impacted by a change, express
the business logic of each field (how is it
computed)
Example: Definition
onchange() → compute()
# Odoo 12
pricelist_id = fields.Many2one()
delivery_id = fields.Many2one()
@api.onchange('partner_id')
def onchange_partner_id(self):
for order in self:
order.pricelist_id = order.partner_id.pricelist_id
order.delivery_id = order.partner_id.pricelist_id
# Odoo 13
pricelist_id = fields.Many2one(
related="partner_id.pricelist_id",
depends="partner_id",
readonly=False,
store=True)
➔ reverse the definition: instead of telling
what field is impacted by a change, express
the business logic of each field (how is it
computed)
Advantages
onchange() → compute()
➔ compute() fields are tested automatically
➔ inheritances simplified
➔ business logic abstraction
➔ code simplification (no need to call
onchange() manually anymore)
Example
l10n_co adds a customer_type field on
account.invoice that depends on
fiscal_position_id?
→ compare onchange vs compute...
# Odoo 13, create an invoice
self.create({
'partner_id': 1,
'line_ids': ([0,0, {'product_id': 2}])
})
# Odoo 13, create another invoice
self.create({
'partner_id': 1,
'payment_term_id': 2,
'line_ids': ([0,0, {
'product_id': 2, 'price_unit': 100.0
}])
})
Status: compute with
readonly=False are in v13.
onchange() still supported but
will be deprecated in the future.
2019
Questions?
Tweet #odooexperience if you enjoyed the presentation
Ad

More Related Content

What's hot (20)

Best Practices in Handling Performance Issues
Best Practices in Handling Performance IssuesBest Practices in Handling Performance Issues
Best Practices in Handling Performance Issues
Odoo
 
Impact of the New ORM on Your Modules
Impact of the New ORM on Your ModulesImpact of the New ORM on Your Modules
Impact of the New ORM on Your Modules
Odoo
 
Common Performance Pitfalls in Odoo apps
Common Performance Pitfalls in Odoo appsCommon Performance Pitfalls in Odoo apps
Common Performance Pitfalls in Odoo apps
Odoo
 
An in Depth Journey into Odoo's ORM
An in Depth Journey into Odoo's ORMAn in Depth Journey into Odoo's ORM
An in Depth Journey into Odoo's ORM
Odoo
 
Node.js File system & Streams
Node.js File system & StreamsNode.js File system & Streams
Node.js File system & Streams
Eyal Vardi
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
Eyal Vardi
 
Using runbot to test all your developments automatically
Using runbot to test all your developments automaticallyUsing runbot to test all your developments automatically
Using runbot to test all your developments automatically
Odoo
 
Asynchronous JS in Odoo
Asynchronous JS in OdooAsynchronous JS in Odoo
Asynchronous JS in Odoo
Odoo
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
Apaichon Punopas
 
Quick flask an intro to flask
Quick flask   an intro to flaskQuick flask   an intro to flask
Quick flask an intro to flask
juzten
 
Load Testing - How to Stress Your Odoo with Locust
Load Testing - How to Stress Your Odoo with LocustLoad Testing - How to Stress Your Odoo with Locust
Load Testing - How to Stress Your Odoo with Locust
Odoo
 
Odoo - Open chatter integration
Odoo - Open chatter integrationOdoo - Open chatter integration
Odoo - Open chatter integration
Odoo
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOwl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
Odoo
 
NestJS
NestJSNestJS
NestJS
Wilson Su
 
ASP.NET Core MVC + Web API with Overview
ASP.NET Core MVC + Web API with OverviewASP.NET Core MVC + Web API with Overview
ASP.NET Core MVC + Web API with Overview
Shahed Chowdhuri
 
Odoo Web Services
Odoo Web ServicesOdoo Web Services
Odoo Web Services
Celine George
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Angular
AngularAngular
Angular
Lilia Sfaxi
 
Developing New Widgets for your Views in Owl
Developing New Widgets for your Views in OwlDeveloping New Widgets for your Views in Owl
Developing New Widgets for your Views in Owl
Odoo
 
File system node js
File system node jsFile system node js
File system node js
monikadeshmane
 
Best Practices in Handling Performance Issues
Best Practices in Handling Performance IssuesBest Practices in Handling Performance Issues
Best Practices in Handling Performance Issues
Odoo
 
Impact of the New ORM on Your Modules
Impact of the New ORM on Your ModulesImpact of the New ORM on Your Modules
Impact of the New ORM on Your Modules
Odoo
 
Common Performance Pitfalls in Odoo apps
Common Performance Pitfalls in Odoo appsCommon Performance Pitfalls in Odoo apps
Common Performance Pitfalls in Odoo apps
Odoo
 
An in Depth Journey into Odoo's ORM
An in Depth Journey into Odoo's ORMAn in Depth Journey into Odoo's ORM
An in Depth Journey into Odoo's ORM
Odoo
 
Node.js File system & Streams
Node.js File system & StreamsNode.js File system & Streams
Node.js File system & Streams
Eyal Vardi
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
Eyal Vardi
 
Using runbot to test all your developments automatically
Using runbot to test all your developments automaticallyUsing runbot to test all your developments automatically
Using runbot to test all your developments automatically
Odoo
 
Asynchronous JS in Odoo
Asynchronous JS in OdooAsynchronous JS in Odoo
Asynchronous JS in Odoo
Odoo
 
Quick flask an intro to flask
Quick flask   an intro to flaskQuick flask   an intro to flask
Quick flask an intro to flask
juzten
 
Load Testing - How to Stress Your Odoo with Locust
Load Testing - How to Stress Your Odoo with LocustLoad Testing - How to Stress Your Odoo with Locust
Load Testing - How to Stress Your Odoo with Locust
Odoo
 
Odoo - Open chatter integration
Odoo - Open chatter integrationOdoo - Open chatter integration
Odoo - Open chatter integration
Odoo
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOwl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
Odoo
 
ASP.NET Core MVC + Web API with Overview
ASP.NET Core MVC + Web API with OverviewASP.NET Core MVC + Web API with Overview
ASP.NET Core MVC + Web API with Overview
Shahed Chowdhuri
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Developing New Widgets for your Views in Owl
Developing New Widgets for your Views in OwlDeveloping New Widgets for your Views in Owl
Developing New Widgets for your Views in Owl
Odoo
 

Similar to New Framework - ORM (20)

Presentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERPPresentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERP
Odoo
 
Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
Andreas Dewes
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
Caserta
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
ddiers
 
Distributed Queries in IDS: New features.
Distributed Queries in IDS: New features.Distributed Queries in IDS: New features.
Distributed Queries in IDS: New features.
Keshav Murthy
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
Night Sailer
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
Tse-Ching Ho
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
AidIQ
 
Odoo from 7.0 to 8.0 API
Odoo from 7.0 to 8.0 APIOdoo from 7.0 to 8.0 API
Odoo from 7.0 to 8.0 API
Mustufa Rangwala
 
Odoo - From v7 to v8: the new api
Odoo - From v7 to v8: the new apiOdoo - From v7 to v8: the new api
Odoo - From v7 to v8: the new api
Odoo
 
Fatc
FatcFatc
Fatc
Wade Arnold
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
Shinya Ohyanagi
 
MongoDB Meetup
MongoDB MeetupMongoDB Meetup
MongoDB Meetup
Maxime Beugnet
 
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaSolutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Guido Schmutz
 
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
ddiers
 
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache KafkaSolutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Guido Schmutz
 
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
confluent
 
PHP and COM
PHP and COMPHP and COM
PHP and COM
Wez Furlong
 
MongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: Keynote
MongoDB
 
ETL Patterns with Postgres
ETL Patterns with PostgresETL Patterns with Postgres
ETL Patterns with Postgres
Martin Loetzsch
 
Presentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERPPresentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERP
Odoo
 
Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
Andreas Dewes
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
Caserta
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
ddiers
 
Distributed Queries in IDS: New features.
Distributed Queries in IDS: New features.Distributed Queries in IDS: New features.
Distributed Queries in IDS: New features.
Keshav Murthy
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
Night Sailer
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
Tse-Ching Ho
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
AidIQ
 
Odoo - From v7 to v8: the new api
Odoo - From v7 to v8: the new apiOdoo - From v7 to v8: the new api
Odoo - From v7 to v8: the new api
Odoo
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
Shinya Ohyanagi
 
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaSolutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Guido Schmutz
 
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
ddiers
 
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache KafkaSolutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Guido Schmutz
 
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
confluent
 
MongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: Keynote
MongoDB
 
ETL Patterns with Postgres
ETL Patterns with PostgresETL Patterns with Postgres
ETL Patterns with Postgres
Martin Loetzsch
 
Ad

More from Odoo (20)

Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!
Odoo
 
Odoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-ViewerOdoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-Viewer
Odoo
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & Strategy
Odoo
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14
Odoo
 
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting CapabilityExtending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Odoo
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with Odoo
Odoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use Case
Odoo
 
Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?
Odoo
 
Rock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsRock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced Operations
Odoo
 
Transition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organizationTransition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organization
Odoo
 
Synchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the CrisisSynchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the Crisis
Odoo
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with Odoo
Odoo
 
Down Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in OdooDown Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in Odoo
Odoo
 
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach foodOdoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to Odoo
Odoo
 
Preventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine LearningPreventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine Learning
Odoo
 
Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification
Odoo
 
Instant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping LabelInstant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping Label
Odoo
 
How Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 FoldHow Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 Fold
Odoo
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to Odoo
Odoo
 
Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!
Odoo
 
Odoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-ViewerOdoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-Viewer
Odoo
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & Strategy
Odoo
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14
Odoo
 
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting CapabilityExtending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Odoo
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with Odoo
Odoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use Case
Odoo
 
Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?
Odoo
 
Rock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsRock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced Operations
Odoo
 
Transition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organizationTransition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organization
Odoo
 
Synchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the CrisisSynchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the Crisis
Odoo
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with Odoo
Odoo
 
Down Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in OdooDown Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in Odoo
Odoo
 
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach foodOdoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to Odoo
Odoo
 
Preventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine LearningPreventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine Learning
Odoo
 
Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification
Odoo
 
Instant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping LabelInstant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping Label
Odoo
 
How Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 FoldHow Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 Fold
Odoo
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to Odoo
Odoo
 
Ad

Recently uploaded (20)

www.visualmedia.com digital markiting (1).pptx
www.visualmedia.com digital markiting (1).pptxwww.visualmedia.com digital markiting (1).pptx
www.visualmedia.com digital markiting (1).pptx
Davinder Singh
 
LDMMIA Bday celebration 2025 Gifts information
LDMMIA Bday celebration 2025 Gifts informationLDMMIA Bday celebration 2025 Gifts information
LDMMIA Bday celebration 2025 Gifts information
LDM Mia eStudios
 
Smart Home Market Size, Growth and Report (2025-2034)
Smart Home Market Size, Growth and Report (2025-2034)Smart Home Market Size, Growth and Report (2025-2034)
Smart Home Market Size, Growth and Report (2025-2034)
GeorgeButtler
 
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Lviv Startup Club
 
India Advertising Market Size & Growth | Industry Trends
India Advertising Market Size & Growth | Industry TrendsIndia Advertising Market Size & Growth | Industry Trends
India Advertising Market Size & Growth | Industry Trends
Aman Bansal
 
BeMetals_Presentation_May_2025 .pdf
BeMetals_Presentation_May_2025      .pdfBeMetals_Presentation_May_2025      .pdf
BeMetals_Presentation_May_2025 .pdf
DerekIwanaka2
 
Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Cloud Stream Part II Mobile Hub V1 Hub Agency.pdfCloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Brij Consulting, LLC
 
From Sunlight to Savings The Rise of Homegrown Solar Power.pdf
From Sunlight to Savings The Rise of Homegrown Solar Power.pdfFrom Sunlight to Savings The Rise of Homegrown Solar Power.pdf
From Sunlight to Savings The Rise of Homegrown Solar Power.pdf
Insolation Energy
 
waterBeta white paper - 250202- two-column.docx
waterBeta white paper - 250202- two-column.docxwaterBeta white paper - 250202- two-column.docx
waterBeta white paper - 250202- two-column.docx
Peter Adriaens
 
Alan Stalcup - The Enterprising CEO
Alan  Stalcup  -  The  Enterprising  CEOAlan  Stalcup  -  The  Enterprising  CEO
Alan Stalcup - The Enterprising CEO
Alan Stalcup
 
CGG Deck English - Apr 2025-edit (1).pptx
CGG Deck English - Apr 2025-edit (1).pptxCGG Deck English - Apr 2025-edit (1).pptx
CGG Deck English - Apr 2025-edit (1).pptx
China_Gold_International_Resources
 
Level Up Your Launch: Utilizing AI for Start-up Success
Level Up Your Launch: Utilizing AI for Start-up SuccessLevel Up Your Launch: Utilizing AI for Start-up Success
Level Up Your Launch: Utilizing AI for Start-up Success
Best Virtual Specialist
 
20250428 CDB Investor Deck_Apr25_vFF.pdf
20250428 CDB Investor Deck_Apr25_vFF.pdf20250428 CDB Investor Deck_Apr25_vFF.pdf
20250428 CDB Investor Deck_Apr25_vFF.pdf
yihong30
 
Strategic Enterprise Management - Unit I.pptx
Strategic Enterprise Management - Unit I.pptxStrategic Enterprise Management - Unit I.pptx
Strategic Enterprise Management - Unit I.pptx
PrekshyaRana
 
Treis & Friends One sheet - Portfolio IV
Treis & Friends One sheet - Portfolio IVTreis & Friends One sheet - Portfolio IV
Treis & Friends One sheet - Portfolio IV
aparicioregina7
 
From Dreams to Threads: The Story Behind The Chhapai
From Dreams to Threads: The Story Behind The ChhapaiFrom Dreams to Threads: The Story Behind The Chhapai
From Dreams to Threads: The Story Behind The Chhapai
The Chhapai
 
Alec Lawler - A Passion For Building Brand Awareness
Alec Lawler - A Passion For Building Brand AwarenessAlec Lawler - A Passion For Building Brand Awareness
Alec Lawler - A Passion For Building Brand Awareness
Alec Lawler
 
Avoiding the China Tariffs: Save Costs & Stay Competitive
Avoiding the China Tariffs: Save Costs & Stay CompetitiveAvoiding the China Tariffs: Save Costs & Stay Competitive
Avoiding the China Tariffs: Save Costs & Stay Competitive
NovaLink
 
Solaris Resources Presentation - Corporate April 2025.pdf
Solaris Resources Presentation - Corporate April 2025.pdfSolaris Resources Presentation - Corporate April 2025.pdf
Solaris Resources Presentation - Corporate April 2025.pdf
pchambers2
 
Kiran Flemish - A Dynamic Musician
Kiran  Flemish  -  A   Dynamic  MusicianKiran  Flemish  -  A   Dynamic  Musician
Kiran Flemish - A Dynamic Musician
Kiran Flemish
 
www.visualmedia.com digital markiting (1).pptx
www.visualmedia.com digital markiting (1).pptxwww.visualmedia.com digital markiting (1).pptx
www.visualmedia.com digital markiting (1).pptx
Davinder Singh
 
LDMMIA Bday celebration 2025 Gifts information
LDMMIA Bday celebration 2025 Gifts informationLDMMIA Bday celebration 2025 Gifts information
LDMMIA Bday celebration 2025 Gifts information
LDM Mia eStudios
 
Smart Home Market Size, Growth and Report (2025-2034)
Smart Home Market Size, Growth and Report (2025-2034)Smart Home Market Size, Growth and Report (2025-2034)
Smart Home Market Size, Growth and Report (2025-2034)
GeorgeButtler
 
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Lviv Startup Club
 
India Advertising Market Size & Growth | Industry Trends
India Advertising Market Size & Growth | Industry TrendsIndia Advertising Market Size & Growth | Industry Trends
India Advertising Market Size & Growth | Industry Trends
Aman Bansal
 
BeMetals_Presentation_May_2025 .pdf
BeMetals_Presentation_May_2025      .pdfBeMetals_Presentation_May_2025      .pdf
BeMetals_Presentation_May_2025 .pdf
DerekIwanaka2
 
Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Cloud Stream Part II Mobile Hub V1 Hub Agency.pdfCloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Brij Consulting, LLC
 
From Sunlight to Savings The Rise of Homegrown Solar Power.pdf
From Sunlight to Savings The Rise of Homegrown Solar Power.pdfFrom Sunlight to Savings The Rise of Homegrown Solar Power.pdf
From Sunlight to Savings The Rise of Homegrown Solar Power.pdf
Insolation Energy
 
waterBeta white paper - 250202- two-column.docx
waterBeta white paper - 250202- two-column.docxwaterBeta white paper - 250202- two-column.docx
waterBeta white paper - 250202- two-column.docx
Peter Adriaens
 
Alan Stalcup - The Enterprising CEO
Alan  Stalcup  -  The  Enterprising  CEOAlan  Stalcup  -  The  Enterprising  CEO
Alan Stalcup - The Enterprising CEO
Alan Stalcup
 
Level Up Your Launch: Utilizing AI for Start-up Success
Level Up Your Launch: Utilizing AI for Start-up SuccessLevel Up Your Launch: Utilizing AI for Start-up Success
Level Up Your Launch: Utilizing AI for Start-up Success
Best Virtual Specialist
 
20250428 CDB Investor Deck_Apr25_vFF.pdf
20250428 CDB Investor Deck_Apr25_vFF.pdf20250428 CDB Investor Deck_Apr25_vFF.pdf
20250428 CDB Investor Deck_Apr25_vFF.pdf
yihong30
 
Strategic Enterprise Management - Unit I.pptx
Strategic Enterprise Management - Unit I.pptxStrategic Enterprise Management - Unit I.pptx
Strategic Enterprise Management - Unit I.pptx
PrekshyaRana
 
Treis & Friends One sheet - Portfolio IV
Treis & Friends One sheet - Portfolio IVTreis & Friends One sheet - Portfolio IV
Treis & Friends One sheet - Portfolio IV
aparicioregina7
 
From Dreams to Threads: The Story Behind The Chhapai
From Dreams to Threads: The Story Behind The ChhapaiFrom Dreams to Threads: The Story Behind The Chhapai
From Dreams to Threads: The Story Behind The Chhapai
The Chhapai
 
Alec Lawler - A Passion For Building Brand Awareness
Alec Lawler - A Passion For Building Brand AwarenessAlec Lawler - A Passion For Building Brand Awareness
Alec Lawler - A Passion For Building Brand Awareness
Alec Lawler
 
Avoiding the China Tariffs: Save Costs & Stay Competitive
Avoiding the China Tariffs: Save Costs & Stay CompetitiveAvoiding the China Tariffs: Save Costs & Stay Competitive
Avoiding the China Tariffs: Save Costs & Stay Competitive
NovaLink
 
Solaris Resources Presentation - Corporate April 2025.pdf
Solaris Resources Presentation - Corporate April 2025.pdfSolaris Resources Presentation - Corporate April 2025.pdf
Solaris Resources Presentation - Corporate April 2025.pdf
pchambers2
 
Kiran Flemish - A Dynamic Musician
Kiran  Flemish  -  A   Dynamic  MusicianKiran  Flemish  -  A   Dynamic  Musician
Kiran Flemish - A Dynamic Musician
Kiran Flemish
 

New Framework - ORM

  • 1. 2019 Odoo Experience New Framework / ORM Fabien Pinckaers • Founder
  • 2. Odoo 13: the biggest ORM refactoring since OpenERP 8
  • 3. Odoo 13: the biggest ORM refactoring since OpenERP 8 In-Memory ORM
  • 5. Performance: SQL 4x less SQL queries, on average → faster perf on larger DB
  • 7. Evolution of The ORM for Perf Improvements
  • 8. Single Cache Instead of one cache per env / context ➔ Stored fields have a single value ➔ Computed, non-stored fields’ value depends on specific keywords in the context ➔ ex: translatable, properties v12 cache structure: ➔ {env: {field: {id: value}}} v13 cache: ➔ {field: {id: value}} v13 cache, @depends_context fields: ➔ {field: {id: {context_keys: value}}} # Odoo 12 self.field # SELECT r = self.with_context(key=val) # new cache r.field # SELECT self.sudo().field # new cache + SELECT # Odoo 13 self.field # SELECT r = self.with_context(key=val) r.field self.sudo().field
  • 9. Prefer In-Memory updates Instead of SQL queries ➔ put in cache, instead of writing in DB ➔ env.all.towrite contains values to UPDATE ➔ nearly never invalidate cache, update it instead (e.g. changing a many2one, will update cached values of its one2many) ➔ flush([fields]): ◆ write in DB (minimize updates) ◆ recompute optional fields ◆ called at end of rpc ➔ create() does INSERT directly # Odoo 12 self.name = 'test' # UPDATE + invalid cache self.name = 'test2' # UPDATE + invalid cache self.name # SELECT # Odoo 13 self.name = 'test' # put in cache self.name = 'test2' # put in cache self.name # get from cache self.flush() # UPDATE
  • 10. Dependencies In-Memory class order(Model): discount = Float() line_ids = One2many('order_id') class order_line(Model): order_id = Many2one('order') price = Float() subtotal = Float(compute="get_total") @api.depends('price','order_id.discount') def get_total(self): self.subtotal = self.price * self.order_id.discount # Odoo 12 for order in self: order.discount = 10.0 # SELECT id WHERE order_id # UPDATE order # Odoo 13 for order in self: order.discount = 10.0 # no SQL self.flush() # UPDATE order WHERE id IN () Whenever possible ➔ instead of SQL query, get inverse field, ex: to evaluate @depends(‘order_id’), check value of line_ids in the cache ➔ usually avoids a SELECT as the implementation of the compute will read the same object ➔ if no inverse field, fall back to SQL query (e.g. many2one without a one2many) ➔ when create(), set one2many to []
  • 11. Delay computed field As late as possible ➔ compute fields: ◆ only if you read it ◆ or if you need to flush in the DB ➔ as the old value stays in memory, we can optimize to not recompute if the value do not change # odoo 12 for line in order: line.product_qty = 1 # mark to recompute # compute l.subtotal, o.total line.discount = 10 # mark to recompute # compute l.subtotal, o.total line.price = 100 # mark to recompute # compute l.subtotal, o.total # odoo 13 for line in order: line.product_qty = 1 # mark to recompute line.discount = 10 # mark to recompute line.price = 100 # mark to recompute self.flush() # recompute all lines & orders
  • 12. Delay SQL updates As late as possible ➔ save all changes in a self.env.all.towrite ➔ optimize updates, to minimize queries: update several records at once update several fields at once # odoo 12 for line in order: line.state = 'draft' # UPDATE ... WHERE ID = x # odoo 13 for line in order: line.state = 'draft' self.flush() # UPDATE ... WHERE ID IN (...)
  • 13. Optimize dependency tree to reduce python & sql computations v12: recursive dependencies change order.discount → order_line.subtotal depends on it → to recompute subtotal → order_id.total depends on it (for each line) → to recompute order.total v13: optimized dependency trees change order.discount → to recompute total → order_line.subtotal depends on it → to recompute order_line.subtotal class order(Model): discount = Float() line_ids = One2many('order_id') class order_line(Model): order_id = Many2one('order') price = Float() subtotal = Float(compute="get_total") @api.depends('price','order_id.discount') def get_total(self): self.subtotal = self.price * self.order_id.discount # Impact of: order.discount = 1
  • 14. browse() optimization Avoid multiple format conversion ➔ cache format similar to DB to avoid conversion: None instead of False 4 instead of (4,) for many2one ➔ don’t convert to read() format, for browse records # Odoo 12 self.field → prefetch → read → _read SQL query convert_to_cache put in cache → get from cache (convert_to_record) → convert_to_read # Odoo 13 self.field → prefetch _read SQL query put in cache
  • 15. And a lot of code cleanup, and Python optimization.
  • 17. on the way to deprecate onchange()
  • 18. Who can tell what onchange_partner_id() does on a sale.order? (not me)
  • 19. How is the sale.order pricelist_id field computed? And the delivery address? (much easier to express)
  • 20. Compute vs onchange Computed Fields ✓ Work in Python module & JS client ✓ Clean dependency graph ✓ Express a business logic ✓ Separation of business concepts ⛌ Field readonly (but can be inverted) onchange() method ⛌ Only work in JS client ⛌ No dependency graph: recursion ⛌ interface logic, not business logic ⛌ Business concepts aggregated ✓ Allow to edit the field The new framework supports fields with: compute=”...”, readonly=False compute method might not set a value
  • 22. Example: Definition onchange() → compute() # Odoo 12 pricelist_id = fields.Many2one() delivery_id = fields.Many2one() @api.onchange('partner_id') def onchange_partner_id(self): for order in self: order.pricelist_id = order.partner_id.pricelist_id order.delivery_id = order.partner_id.pricelist_id # Odoo 13 pricelist_id = fields.Many2one(compute="comp_pl_id", readonly=False) delivery_id = fields.Many2one(compute="comp_delivery_id") @api.depends('partner_id') def compute_pricelist_id(self): for order in self: self.pricelist_id = order.partner_id.pricelist_id @api.depends('partner_id') def compute_delivery_id(self): for order in self: self.delivery_id = order.partner_id.pricelist_id ➔ reverse the definition: instead of telling what field is impacted by a change, express the business logic of each field (how is it computed)
  • 23. Example: Definition onchange() → compute() # Odoo 12 pricelist_id = fields.Many2one() delivery_id = fields.Many2one() @api.onchange('partner_id') def onchange_partner_id(self): for order in self: order.pricelist_id = order.partner_id.pricelist_id order.delivery_id = order.partner_id.pricelist_id # Odoo 13 pricelist_id = fields.Many2one( related="partner_id.pricelist_id", depends="partner_id", readonly=False, store=True) ➔ reverse the definition: instead of telling what field is impacted by a change, express the business logic of each field (how is it computed)
  • 24. Advantages onchange() → compute() ➔ compute() fields are tested automatically ➔ inheritances simplified ➔ business logic abstraction ➔ code simplification (no need to call onchange() manually anymore) Example l10n_co adds a customer_type field on account.invoice that depends on fiscal_position_id? → compare onchange vs compute... # Odoo 13, create an invoice self.create({ 'partner_id': 1, 'line_ids': ([0,0, {'product_id': 2}]) }) # Odoo 13, create another invoice self.create({ 'partner_id': 1, 'payment_term_id': 2, 'line_ids': ([0,0, { 'product_id': 2, 'price_unit': 100.0 }]) })
  • 25. Status: compute with readonly=False are in v13. onchange() still supported but will be deprecated in the future.
  • 26. 2019 Questions? Tweet #odooexperience if you enjoyed the presentation