ODOO COMMUNITY UPGRADE
Moving up a major Odoo version is not an update: it is a one-way change to your database, and it is not something you want to get wrong. Here is how we do it for you — a new system on our own servers, your current one left untouched while we work — and, underneath, the exact commands a developer would run.
The difference that matters
Odoo uses two words that sound the same and are not. An update gets you the newest revision of the software you already run. An upgrade moves your database to a new major release — 18 to 19, or 19 to 20 — and it transforms the data itself. It is one-way: there is no supported way back down, and it is not a licence change, not a move to a different edition and not a switch of hosting provider.
Three things about it are worth knowing before anyone touches your system.
It happens one major version at a time. A jump from 17 to 20 is three migrations, not one: 17 → 18, 18 → 19, 19 → 20. Skipping a version is not a supported path anywhere in the Odoo ecosystem.
It is done on a copy, never on the live database. Everyone who has written about this — Odoo's own documentation, the OCA's OpenUpgrade project, and every practitioner we have watched — starts by taking a backup and working on a duplicate. You find out what broke on the copy, not in front of your customers.
Your own customisations are the part that needs work. A module built for your business does not move by itself: its code has to be brought up to the target version, and the renames that would otherwise lose data need migration scripts written for it. Odoo's documentation says it plainly — an upgrade is blocked until a version of your custom modules exists for the release you are moving to.
Then the route itself. Odoo sells an upgrade path for Enterprise, and for Odoo Community the open-source answer is the OCA's OpenUpgrade project. The OpenUpgrade documentation states that Odoo Community Edition does not support migrations between major releases, and records that OpenUpgrade is the solution Odoo's own founder recommends for it. It is a real project, maintained by the community association, and it is the route a developer will use on a Community database.
The ODOO4projects way
You do not have to do any of this yourself. If your business runs on Odoo Community and you want the version moved without hiring someone to work through the sequence on this page, this is what we do instead.
You open a support ticket and tell us what you have. We look at your database first — its version, its customisations, whether it is something we can move — and we tell you what we find. Then we send you a link to a secure form where you upload your database. When we have it, we spin up a new server for you on our own infrastructure and hand you the credentials. Your existing system keeps running the whole time, because we are not touching it: we work on the database you sent us and the new server we built.
If you would rather see a number first: which plan you need depends on the modules you run, and the plans are here — See the plans. The upgrade itself is not priced on that page; we come back to you after we have looked at your database.
That last point is the whole reason to do it this way. On our service you are not migrating your live database in the evening after the shop closes. You are looking at a second system, in a new version, with your data in it, and you can compare the two before you decide anything.
Our migration service documents support for databases on Odoo 17, 18 and 19, main releases only — patch releases such as 18.1 or 17.2 are not supported anywhere in our service. If your database is older than 17, we can still help you get it to a supported release, but only after reviewing it to check compatibility. New instances on our servers can be created on Odoo 19 or Odoo 20, so if you are moving to 20 specifically, say so in the ticket: the version you are going to matters more than the version you are on.
On the AI side, here is a case we have actually published. Copying invoices from one Odoo instance to another by hand is slow and easy to get wrong, so we did it with a workflow instead: records written from an Odoo 19 system into a new Odoo 20 system, driven by an automation workflow and an MCP server pointed at the new system. Three rules made it safe — the invoice number and date never change, the contact is looked up rather than guessed, the product is looked up rather than guessed — and one hard constraint: if a contact or a product is missing, the run fails loudly rather than creating a near-duplicate. Before releasing it on the rest, we checked one invoice end to end: number, date, contact, product lines.
One thing we will not blur, because it is the difference between us and a salesman. The MCP server we ship inside our own management console does hosting operations. It restarts a server, uploads a module, adds or checks a domain, manages backups and reads a log file — that is the published list, and it is a real convenience if you use an AI assistant. It is not a data-migration engine and we do not describe it as one. The import work above was done with an automation workflow and a third-party MCP; the AI was doing the tedious part and being checked by a human, exactly as it should be.
And the honest limit, in the words of the project that knows this best. The OpenUpgrade documentation names the export-and-import alternative and prices it plainly: you recover only some of your data, and in particular you do not get the history and the links between records — the invoices for each customer, for example. That is the risk of any route that moves documents into a fresh system, and it is why, if you take that route with us, you ask us one question before you approve anything: which records will be in the new database, and which will not. We would rather you ask it than assume it.
The published path
This is the sequence that Odoo's documentation, the OpenUpgrade project and the recorded workshops all agree on. Nothing here is ours and nothing here is secret — it is the published path, in the order it is done.
That is the honest shape of it: preparation is the long part, the migration itself is the short part, and the copy is what you are allowed to break.
For your developer
If you are running Odoo Community yourself and you would rather do this in-house than have us do it, these are the commands. They are quoted from the documentation they come from, and each one is labelled with what you must substitute and what that source warns about. Nothing below has been run by us against your database, and no command published by us runs on our own servers — our service starts with a support ticket, not a terminal.
Odoo documents an upgrade platform that works for on-premise installations from the command line. Odoo's documentation states the migration scripts it runs are not open source and come with Enterprise — but the platform itself will upgrade a self-hosted database.
# upgraded TEST database
python <(curl -s https://upgrade.odoo.com/upgrade) test -d <your db name> -t <target version>
# production upgrade
python <(curl -s https://upgrade.odoo.com/upgrade) production -d <your db name> -t <target version>
# general help
python <(curl -s https://upgrade.odoo.com/upgrade) --help
Substitute: <your db name> is the database on the machine you
run the command from, and <target version> is the release you are moving to —
17.0, 18.0 or 19.0, matching the pricing selector on our own plans page.
What Odoo's documentation requires next to those three lines, because it changes whether they
work: the script needs the usual Linux commands present on the machine; the system user running it
needs access to your PostgreSQL database (the standard PostgreSQL client environment, such as
.pgpass); and the machine must reach the upgrade platform on TCP 443 and on a port in
the range 32768-60999, so a firewall may need an exception. The copy you upload is submitted
without a filestore, so the upgraded database has to have the production filestore merged into it
before you test it. The download contains dump.sql and a filestore folder, and only
the person who requested the upgrade can download the result.
# 1. OpenUpgrade for the TARGET version (the branch is the target major version)
git clone --depth 1 --branch <TARGET>.0 https://github.com/OCA/OpenUpgrade.git
# 2. helper library — the line the OpenUpgrade docs use
pip install "git+https://github.com/OCA/openupgradelib.git@master#egg=openupgradelib"
# 3. put the clone on the add-ons path of the <TARGET> Odoo config
# addons_path = <your own addons>,</abs/path>/OpenUpgrade
# 4. migrate the copy of the database
<odoo-bin> -c /etc/odoo/<TARGET>.conf \
-d <DB> \
--upgrade-path=/abs/path/OpenUpgrade/openupgrade_scripts/scripts \
-u all --stop-after-init \
--load=base,web,openupgrade_framework
# 5. finish: a plain update, no migration parameters
<odoo-bin> -c /etc/odoo/<TARGET>.conf -d <DB> -u all --stop-after-init
Substitute four things: <TARGET> is the target major version
(17, 18 or 19 — not the version you are coming from); <DB> is the copy you are
migrating, never the live database; <odoo-bin> is the binary for the target
version, and what it is called depends on how you installed Odoo (odoo-bin,
odoo, or the Docker equivalent); and both absolute paths are your own — the add-ons
path and the location of the OpenUpgrade clone.
Two details worth carrying from the project's own documentation: the
openupgrade_framework part of that command is a set of patches that, among other
things, stops Odoo dropping the columns and tables of fields that no longer exist — which is one
of the ways a migration loses data. And the environment variable
OPENUPGRADE_USE_DEMO=yes keeps demo data in the migrated database when you want it.
# Odoo's own code-rewrite command (it runs the scripts in odoo/upgrade_code)
<odoo-bin> upgrade_code --from <FROM> --to <TO> --dry-run
Substitute <FROM> and <TO> with the two
major versions (18 and 19, for example). Run it with --dry-run first. Odoo's own
command reference calls this command a "best-effort" tool and warns that it is "not silver
bullets" — it rewrites what it can and leaves you a list of what a human still has to change. The
OpenUpgrade community's equivalent for module code is odoo-module-migrator, which
logs INFO for automatic changes, WARNING for things to check and ERROR for things that will not
work at all. Both tools report; neither one thinks.
# stop the service while you work (packaged install; the Odoo docs show this pattern)
sudo service odoo<TARGET> stop
# database dump (PostgreSQL's own tool)
sudo -u postgres pg_dump -Fc -d <DB> -f /path/backup/<DB>.dump
# restore a dump into a fresh database
sudo -u postgres createdb -O <DB_OWNER> <DB_NEW>
sudo -u postgres pg_restore -d <DB_NEW> /path/backup/<DB>.dump
# the filestore lives under Odoo's data directory:
# default on Unix: $XDG_DATA_HOME or ~/.local/share/Odoo or /var/lib/Odoo
# filestore path: <data_dir>/filestore/<DB>
Substitute the database names, the owner, the backup path and the filestore data directory with your own; the filestore is what holds the attachments and documents your records point at, and a database restored without it is a database whose files are missing. These are PostgreSQL's and Odoo's documented procedures, not ours — we do not publish a command that runs on our own servers, because our service starts with a ticket.
Sweat equity
A rented server is cheap. That is the smallest number in this decision. Odoo Community itself is free — you will not find a per-user licence anywhere in this route, because Community does not have one.
What is not in that number is the person. An upgrade on your own server means someone installs the new version, gets the migration code onto the right path, ports the modules your business actually uses, runs the migration until the log stops complaining, checks that the customers, orders and invoices are still there, cleans up what the migration left behind, and then does it again on the production database at a time that suits the business. Odoo's own documentation says the update is most appropriately done by the person who deployed Odoo in the first place. On a rented server, that person is you or someone you pay by the hour — and neither of those lines appears on the invoice. That is the half of the bill nobody prints, and it is the half that lands in your evenings.
We are not going to put a number on your hours, because we have not measured them and a marketing figure would be worse than none. What we will say is the part that is not really about money: while you are doing that work, you are not doing the work you get paid for, and if the migration is wrong you find out from a customer.
Straight answers
No. An update gives you the newest revision of the software you already run. An upgrade moves your database to a new major release — 18 to 19, or 19 to 20 — and transforms the data itself. It is one-way: there is no supported path back down, and it is not a licence change, an edition change or a hosting change.
No. It is one major version at a time: 14 → 15 → 16 → 17 → 18 → 19 → 20. Skipping a version is not a supported path. Our own migration service documents support for databases on Odoo 17, 18 and 19, main releases only — no patch releases — and older databases need a compatibility review first, which starts with a support ticket.
That is the right question to ask, and the honest answer is that it depends on the route. The OpenUpgrade route — a version migration run on your own server — carries the database across and keeps the history and the links between records. The OpenUpgrade documentation warns that the other route, moving documents into a fresh system, recovers only some of your data and loses the history and the links between records — the invoices for each customer, for example. Our service builds you a new database and moves your data into it, so ours is the route to ask about: before you approve anything, ask us to list exactly which records will be in the new database, and which will not. We would rather you ask it than assume it.
Not by themselves. A module written for your business has to have its code brought up to the target version, and any renames that would otherwise lose data need their own migration scripts. Odoo's documentation is direct about it: an upgrade is blocked until a version of your custom modules exists for the release you are moving to. Modules that ship with Odoo and modules from the community association carry their own migration scripts; yours do not, and someone has to write them.
We publish no price and no duration for the upgrade service, and we are not going to invent one here. What we do publish is how it starts: you open a support ticket, we review your database for compatibility, and we come back to you. If you are weighing it against doing it yourself, the honest comparison is not the server rental — it is your own hours, which never appear on that invoice.
To run the commands in the technical section, yes — or someone comfortable in a terminal with PostgreSQL. To have us do it, no: that is the point of the service. You send the database, we build the new system on our infrastructure, and you get credentials.
Yes, and you should. Whoever does the work migrates a copy first — that is the first rule of the whole process, in Odoo's documentation and in the OpenUpgrade project's — and the migrated copy is what you inspect before anything happens to the system your business is running on. Our service follows the same principle: we build the new system on our own servers and you compare it with the old one.
Yes, that is exactly what our migration service is for. You open a support ticket, we send you a secure form to upload your database, and we spin up a new server for you on our infrastructure and provide the credentials. Databases on Odoo 17, 18 and 19, main releases only; older ones after a compatibility review.
Open a support ticket, we review your database for compatibility, and we come back to you.