7 - Using the Odoo Shell (odoo-bin shell) for Debugging
Welcome back! So far, we have been starting the Odoo server and letting it run in the background while we look at the web browser. But what happens when you write a complex function and it isn't working?
Do you really want to keep adding print() statements, restarting the server, and refreshing your browser over and over again? Absolutely not. That takes too much time!
This is where the Odoo Shell comes in. It is a secret weapon that allows you to open a live Python terminal connected directly to your Odoo database. Let's learn how to use it to debug like a senior developer.
1. Launching the Shell
To enter the shell, we use our trusty odoo-bin script, but we add the word shell right after it. You must also specify which database you want to connect to.
Open your terminal and run:
python3 odoo-bin shell -c odoo.conf -d your_database_name
Once it loads, your terminal prompt will change to >>>. You are now inside a live Python REPL (Read-Eval-Print Loop), but with a massive superpower: Odoo is already loaded into it.
2. The Magic of env
In normal Odoo Python files, you constantly use self.env to interact with the database. Inside the Odoo shell, the framework automatically gives you a global variable called env.
This env variable is your gateway to every single piece of data in your system.
Try typing this into your shell and pressing Enter:
env
(It will return something like <odoo.api.Environment object at 0x7f8b...>. This means you are connected and ready to go!)
3. Real-World Debugging Examples
Let's look at how you can use the shell to test queries and fix data without ever opening the web browser.
Example 1: Counting Records Want to quickly know how many customers are in your database?
env['res.partner'].search_count([])
Example 2: Searching and Looping Let's find all the contacts that are classified as "Companies" and print their names. This is a great way to test if your search domains are written correctly before putting them in your real code!
companies = env['res.partner'].search([('is_company', '=', True)])
for company in companies:
print(company.name, company.email)
Example 3: Checking the Active User Sometimes you need to know what context the system is running under. You can easily check the current user and their active company:
print(env.user.name)
print(env.company.name)
4. The Golden Rule of the Shell: Committing Data
The shell is incredibly safe. By default, Odoo opens the shell in an isolated database transaction. This means you can create, modify, or delete records in the shell, but the moment you type exit() and leave, Odoo cancels everything you did.
This is amazing for safely testing destructive code! But what if you want to save the changes you made?
Let's say you want to use the shell to quickly update a customer's phone number and save it to the database:
# 1. Find the customer
customer = env['res.partner'].search([('name', '=', 'John Doe')], limit=1)
# 2. Update the phone number
customer.write({'phone': '+201234567890'})
# 3. FORCE THE SAVE (Commit the transaction)
env.cr.commit()
If you do not type env.cr.commit(), the phone number will revert back to its old value as soon as you close the terminal.
5. Pro-Tips for the Shell
💡 PRO TIP: Testing Raw SQL While you should always use the Odoo ORM (Object-Relational Mapping) when writing modules, sometimes a senior developer needs to run a raw SQL query to figure out a deep database issue. You can do this right from the shell:
env.cr.execute("SELECT name, email FROM res_partner WHERE active = false")
# Fetch the results as a list of tuples
hidden_contacts = env.cr.fetchall()
print(hidden_contacts)
Exiting the Shell: When you are done debugging, simply type exit() or press Ctrl + D on your keyboard to safely close the connection and return to your normal Ubuntu terminal.
There are no comments for now.