Migrate Odoo 19 to 20
Last updated: October 2026
Migrating Odoo Community Edition from version 19 to 20 involves 186 models added or removed, 35 module merges, and 33 field renames. OCU automates this entire process — upload your database backup and download a production-ready database running Odoo 20.
New to Odoo upgrades? Start with our guide on how to upgrade Odoo Community Edition, which covers the options, the preparation and the steps that apply to every version.
What changes
Between Odoo 19 and 20, the following major changes occur: 2 model renames, 194 constraint changes, and 33 field renames, alongside the 186 models added or removed.
Counted from the Odoo source of each version and from the OCU migration mappings, step by step; Odoo’s internal test modules are left out because they never exist in a production database. Multi-step paths add up their steps.
- Access rights rewritten as ir.access. ir.model.access and ir.rule are gone. One ir.access model holds both model access and record rules: a group, an operation such as r or crud, and an optional domain. Every module ships its access data in the new format, reusing the old external ids.
- Banks folded into bank accounts. res.bank is removed. The bank name, BIC and address are stored on each res.partner.bank row, and acc_number becomes account_number.
- Time off types become work entry types. hr.leave.type is removed. Time off, allocations and accrual plans point at hr.work.entry.type through work_entry_type_id, and working schedules lose their break lines and week types.
- Inventory, accounting and sales restructured. stock.scrap becomes scrap moves, account.group gives way to an account hierarchy, payment states are renamed, pricelist rules switch to discount and markup, and product_uom becomes uom_id on stock moves, purchase lines and bills of materials.
- PostgreSQL 16 and Python 3.12 required. Odoo 20 refuses to start on Python 3.11 or older and needs PostgreSQL 16 or newer. Odoo 19 ran on Python 3.10 and PostgreSQL 13, so many servers need an upgrade of their own.
What changes in detail
Here is a detailed breakdown of the structural changes between Odoo 19 and 20:
Module changes
- 35 modules merged into others. base_iban, base_vat and account_add_gln into account; stock_picking_batch into stock; hr_org_chart, hr_hourly_cost and hr_homeworking into hr; hr_work_entry_holidays into hr_holidays; the website_sale wishlist and comparison modules into website_sale; the POS Adyen, Stripe and Viva.com self-order and restaurant modules into their payment modules; plus a series of localization modules into their parents.
- 1 module rename and 2 new modules installed. website_sale_autocomplete becomes website_address_autocomplete. Purchase alternatives and calls for tender move to the new purchase_alternative module, and the EU VAT number check to l10n_eu_account_vies. OCU installs them when the feature they took over was installed.
Model renames
- 2 model renames. hr.contract.type becomes hr.employee.type and website.base.unit becomes product.base.unit. Most of the 19 to 20 change is models removed and merged rather than renamed: res.bank, hr.leave.type, stock.scrap, account.group, ir.model.access and ir.rule have no direct successor with the same shape.
Field renames
- product_uom becomes uom_id. On stock moves and move lines, purchase order lines, supplier info, manufacturing orders, bills of materials and their lines, unbuild orders and purchase agreement lines.
- Bank account and partner fields. res.partner.bank.acc_number becomes account_number and acc_holder_name becomes holder_name; res.partner peppol_eas and peppol_endpoint become routing_scheme and routing_endpoint.
- 33 field renames in total. Including hr.version.contract_type_id to employee_type_id, account.analytic.line.timesheet_invoice_id to reinvoice_move_id, product.template.expense_policy to reinvoice_policy, pos.order.line.coupon_id to card_id, and several POS and website settings.
Schema and constraints
- 194 constraint changes. 118 constraints added, 50 removed and 26 changed. Data is checked against the new rules before they apply.
- 123 new models, 63 removed. Outside the test modules. Among the removed ones: res.bank, hr.leave.type, stock.scrap, account.group, ir.model.access, ir.rule and product.template.attribute.exclusion.
- Company registry becomes an identifier. company_registry no longer exists on partners and companies. Odoo 20 stores it in the JSON field additional_identifiers, keyed by identifier type.
Breaking changes for custom code
- Anything using ir.model.access or ir.rule. Module security files must be rewritten as security/ir.access.csv. Code that reads or creates access rights or record rules has to use ir.access.
- Anything using res.bank, hr.leave.type, stock.scrap or account.group. Custom modules that inherit or reference these models need porting. The data is migrated; the old model names no longer exist.
- OWL 3 in the web client. The bundled OWL library moves from 2.8 to a 3.0 pre-release. Odoo 20 ships rewrite scripts for module source code (odoo-bin upgrade_code) that cover part of the port.
What OCU converts between Odoo 19 and 20, by area
On top of the generated renames and merges, the 19 to 20 step runs 29 hand-written migration steps across 10 modules. This is where they go:
- Users and access rights. The old access xmlids are freed so Odoo 20 can load its own ir.access data. Access rights and global record rules you created in the database are converted to ir.access. Record rules tied to a group are not converted automatically, because Odoo 20 combines them differently; each one is listed in the log for review and kept in the preserved ir_rule table.
- Employees and time off. Every time off type becomes a work entry type with its name, colour, validation and allocation settings, and time off, allocations and accrual plans are re-pointed to it. Half-day and hourly requests get the new request duration. Two-week and flexible working schedules are converted to the new calendar types, and lunch break lines are removed so they do not count as working time.
- Accounting and payments. Payment states move to the new names (in process becomes paid, paid becomes reconciled). Entries waiting for review keep their place in the To Check list through the new review state. The French chart template code is updated.
- Banks and partners. The bank name, BIC and address of each bank account are copied from its res.bank record onto the account. Company registry numbers move into additional_identifiers without overwriting identifiers that are already there.
- Inventory and products. Scrap orders are carried onto their stock moves with their reason tags and replenish flag. Pricelist rules using percentage or formula are converted to discount or markup with the same computed price. Product attribute exclusions move to the new excluded values field.
- POS, website and discuss. POS employee access levels move to the new cashier, manager and restrictive lists. Website social links move to the company and the zero-price sale setting to the new prevent-sale option. Starred messages become bookmarks.
Prepare the Odoo 20 server
Odoo 20 needs Python 3.12 or newer and PostgreSQL 16 or newer (odoo/release.py). Ubuntu 24.04 ships both; Ubuntu 22.04 and Debian 12 do not. If your Odoo 19 runs on PostgreSQL 13, 14 or 15, set up the database server for Odoo 20 on version 16 or newer.
OCU runs the upgrade on PostgreSQL 16, so the dump you download restores on PostgreSQL 16 or newer.
Pre-flight checklist for 19 to 20
- Update Odoo 19 to the latest 19.0 revision. Then take the backup. It reduces the chance of templates frozen at an older revision.
- List your custom access rules. Access rights and record rules created in Settings > Technical, plus server actions, automated actions and exports that use renamed fields. Group record rules need a manual review after the upgrade.
- Audit your custom modules. Run ./odoo-bin upgrade_code --addons-path=/path/to/custom_addons --from 19.1 --dry-run from Odoo 20 on a copy of your addons, then search for res.bank, hr.leave.type, account.group, stock.scrap, ir.model.access, ir.rule, acc_number and product_uom.
- Check your third-party modules. They stay installed with their data, but their views are switched off until you install Odoo 20 versions of them. Ask vendors and check the OCA repositories for 20.0 branches.
- Record control figures. Trial balance, receivables and payables, stock valuation, time off balances per employee, payments waiting for reconciliation. Compare them after the test run.
- Back up with the filestore. Use the .zip backup from the database manager so attachments and images come along.
- Run a test, restore it on staging, try your daily flows. Quotation to invoice, bank account details on partners, receipts and deliveries, time off requests and approvals, POS sessions if you use POS.
Before you migrate
- Back up your database. Create a fresh backup from Odoo’s database manager (Settings → Database Manager). The .zip format includes your filestore.
- Note your installed modules. Check Settings → Apps for any third-party or custom modules. These will need updated versions for Odoo 20 after migration.
- Run a test migration first. Test migrations are free and unlimited. Verify the result before committing a production credit.
- Plan your custom module updates. OCU handles standard Odoo modules. Custom or third-party modules need separate updates for Odoo 20 compatibility.
How it works
- Upload your .zip, .sql, or .dump backup. We auto-detect the source version.
- Migrate. We handle schema changes, module merges, field renames, and data migration.
- Download your upgraded backup, ready for Odoo 20.
What OCU handles automatically
- Schema changes. Column types, table renames, new required fields — all structural database changes are applied automatically.
- Module merges. When Odoo consolidates modules between versions, OCU updates the module registry and migrates data to the new locations.
- Field renames. Fields that change names between versions are renamed in the database, including references in domains, filters, and server actions.
- Constraint validation. New CHECK and UNIQUE constraints are validated against your data, with automatic fixes for common violations.
- View updates. Inherited views are reset so Odoo 20 can reload them from the updated XML definitions.
- Filestore. Your attachments, images, and documents are preserved and included in the output.
Pricing
Test migrations are free and unlimited — run as many as you need to validate the upgrade. The output is neutralized (emails disabled, crons off) so it’s safe to explore but not for production use.
Production migrations cost one credit (99€), charged only when the migration completes successfully. If the migration fails, no credit is consumed. One credit covers the full path regardless of how many steps are involved.
Frequently asked questions
- Can OCU migrate Odoo 19 to 20 now?
- Yes. Upload an Odoo 19 Community backup and choose 20. Test migrations are free; a production migration uses one credit (€99), charged only when it completes successfully.
- What happens to my access rights and record rules?
- Standard access rights are reloaded by the Odoo 20 modules. Access rights and global record rules you created yourself are converted to ir.access. Record rules tied to a group are kept in the database but not converted, because Odoo 20 combines them differently; the migration log lists each one so you can recreate it.
- Will employees keep their time off balances?
- Yes. Each time off type becomes a work entry type, and time off, allocations and accrual plans are re-pointed to it, so balances and history stay attached. Check a few employees on the test result before going live.
- What do I need on the server for Odoo 20?
- Python 3.12 or newer and PostgreSQL 16 or newer. Odoo 19 needed Python 3.10 and PostgreSQL 13, so many servers that run 19 today need a PostgreSQL upgrade, and often a newer operating system, before they can run 20.
- Does OCU handle custom modules during migration?
- OCU migrates the standard Odoo Community modules. Custom and third-party modules stay installed with their data tables preserved, but their views are disabled so they cannot break the upgrade. After the migration, install versions of those modules written for Odoo 20.
- Can I go from Odoo 16, 17 or 18 straight to 20?
- Yes. Upload the older backup and choose 20; OCU runs each intermediate step in one job and charges one credit for the whole chain. Odoo 15 databases can go to 20 the same way.
Other migration paths
- Odoo 18 to 20 — 315 models added or removed, 60 module merges.
- Odoo 17 to 20 — 470 models added or removed, 85 module merges.
- Odoo 16 to 20 — 604 models added or removed, 109 module merges.
- Odoo 15 to 20 — 751 models added or removed, 132 module merges.
Further reading
- How to Upgrade Odoo Community Edition — Step-by-step guide covering all migration approaches.
- Odoo Migration Checklist — Everything to prepare before, during, and after upgrading.
- Odoo upgrade errors — Fixes for the error messages that stop real upgrades.
- What's New in Odoo 20 — Every verified breaking change in the 19→20 step.
- Pricing — Free test migrations, 99€ production credits.
Ready to migrate Odoo 19 to 20?
Free test migrations, unlimited runs. No credit card required.
Start your free test migration