When To Use The Shell Instead Of The
UI
The shell offers power and speed that the UI simply can't match,
especially for technical tasks.
Instantly run code and commands instead of clicking through
multiple screens in the UI
Access any data or method in the system, not just what the interface
exposes to you
Directly find and fix broken data rather than just seeing error
messages
Update thousands of records at once instead of editing them one by
one
Starting The Shell On Your Local
Machine
Setting up the Odoo Shell on your development machine is
straightforward. Follow these simple steps:
Open Terminal
Launch your terminal application
Navigate To Odoo Folder
Change directory to your Odoo project location
Run Shell Command
Execute:
./odoo-bin shell -d your_database_name
If you use a configuration file, you can simplify this with:
./odoo-bin shell -c [Link]
Starting The Shell On [Link] Platform
[Link] provides a secure way to access the shell for your production or
staging environments.
Access SSH Tab
Navigate to your [Link] project dashboard and click on the SSH tab
Copy SSH Command
Copy the provided SSH connection string
Connect via Terminal
Paste and execute the SSH command in your terminal
Launch Shell
Once connected, simply type:
odoo-bin shell
The [Link] platform automatically knows your database, making this
process simpler than local setup.
The 'env' Object: Your Master Key
Once the shell loads, you gain access to the powerful 'env' object - your
gateway to the entire Odoo application.
What Is env?
The environment object that gives you access to all models, records,
and functionality within your Odoo instance.
How To Use It
Access any model through dictionary syntax:
Partners = env['[Link]']
Products = env['[Link]']
Think of 'env' as your master key that unlocks every door in the Odoo
system. With it, you can access any model, read or modify any data, and
execute any method - all from a single starting point.
Finding And Reading Data
Before making changes, you need to locate the relevant records. The shell
provides powerful methods for searching and browsing data.
search([...])
Find records using domain filters:
azure_interior = env['[Link]'].search([
('name', '=', 'Azure Interior')
])
Returns a recordset (even if empty)
browse(...)
Access records directly by ID:
product_5 = env['[Link]'].browse(5)
if product_5.exists():
print(f"Found: {product_5.name}")
Faster when you already know the record ID
Recordsets behave like collections but have special properties and
methods specific to Odoo. You can iterate through them, filter them, and
access their fields directly.
Creating And Updating Data
The shell truly shines when it comes to data manipulation. You can create
new records or modify existing ones with just a few lines of code.
Create Records
new_tag = env['[Link]'].create({
'name': 'VIP Customer'
})
Creates a new record from a dictionary of values
Update Records
azure_interior.write({
'category_id': [(4, new_tag.id)]
})
Commit And Rollback
One of the most powerful aspects of the shell is that changes aren't
permanent until you explicitly commit them.
[Link]()
Permanently saves all changes you've made to the database. Once
committed, changes cannot be undone except by making new changes.
[Link]()
print("Changes saved to database.")
[Link]()
Cancels all uncommitted changes since your last commit. This is your
"undo" button and primary safety mechanism.
[Link]()
print("All changes cancelled.")
This transaction system provides a powerful safety net - you can experiment,
test changes, and only make them permanent when you're confident they're
correct.
Testing Your Code Without UI Interaction
The shell allows you to test your custom methods and even built-in Odoo
functionality without clicking through the interface.
1 Find A Record
sale_order = env['[Link]'].search([], limit=1)
2 Test Custom Method
# Your custom method
discount = sale_order._calculate_special_discount()
print(f"Discount: {discount}")
3 Test Built-in Actions
print(f"Before: {sale_order.state}")
sale_order.action_confirm()
print(f"After: {sale_order.state}")
4 Rollback Changes
[Link]() # Undo test changes
This approach dramatically speeds up development by eliminating the need to
perform lengthy UI interactions for each test iteration.
Making Safer Changes With
Savepoints
When working with multiple records, savepoints let you handle errors
more gracefully than a full rollback.
The Problem
A full rollback undoes ALL changes since your last commit. When
processing many records, one failure would cancel all successful
updates.
The Solution: Savepoints
Create checkpoints that let you roll back to a specific point:
for product in products_to_update:
try:
with [Link]():
[Link]({'price': [Link] * 1.10})
except Exception as e:
print(f"Skipping {[Link]}: {e}")
Savepoints are like mini-transactions within your main transaction. If an
error occurs within the savepoint block, only those specific changes are
undone, while successful changes remain.
Fixing Bugs That Crash The UI
The shell is often the only way to resolve data corruption issues that prevent
the UI from functioning.
Identify Problem
A sales order is crashing when viewed because its customer was
accidentally deleted
Access Broken Record
broken_so = env['[Link]'].browse(12345)
Verify Issue
if not broken_so.partner_id:
print("Customer missing!")
Fix Data
broken_so.write({'partner_id': 1})
[Link]()
This approach bypasses the UI entirely, letting you fix data that would
otherwise be inaccessible due to errors or validation constraints.
Emergency Module Uninstallation
When a faulty module breaks your entire system, the shell may be your
only recovery option.
Identify Problem Module
broken_module = env['[Link]'].search([
('name', '=', 'problematic_addon')
])
Verify Installation Status
if broken_module and broken_module.state == 'installed':
print("Found the broken module")
Force Uninstallation
broken_module.button_immediate_uninstall()
[Link]()
This technique can recover systems that won't even start normally due to
errors in installed modules.
Interactive Debugging With PDB
The most powerful debugging technique is using Python's built-in
debugger (pdb) to pause execution and inspect variables in real-time.
1 Import Debugger
import pdb
2 Set Breakpoint
partner = env['[Link]'].browse(1)
pdb.set_trace() # Execution stops here
partner.do_something_complex()
3 Debug Commands
n: Run next line
s: Step into function
c: Continue execution
Type variable names to inspect values
This technique gives you X-ray vision into your code, allowing you to see
exactly what's happening as it executes and identify the root cause of
complex bugs.
Thank You!
Thank you for following this guide
to mastering the Odoo Shell.
Happy coding!
Have questions or want to
connect?
Feel free to reach out on LinkedIn
for any Odoo development
discussions.
_ Amr Gaber
Presentation created by: Amr Gaber