Zum Inhalt springen

Odoo 17 auf 19

Ein Bericht
31. Juli 2026 durch
Odoo 17 auf 19
Fluxpunkt GmbH, Fabian Wolf

Das große Update unseres ERP-Systems

Ende Juli 2026 haben wir unser eigenes Odoo-System von Version 17 auf 19 gehoben — mit Website, Webshop, Ticketsystem, Abo-Abrechnung, Lizenzverwaltung, Zeiterfassung und einem knappen Dutzend eigener Modulen.

Das Update sollte die Basis für einen vollständig neu entwickelten Bestellprozess werden, der die Besonderheiten unserer Produkte abbilden kann. Wir wollten das nicht zwei Mal entwickeln, erst für Odoo 17, dann für Odoo 19, also standen wir unter Druck...

Der Upgrade-Service hat die Datenbank sauber migriert. Alles, was danach kam, mussten wir selbst finden. Hier ist die vollständige Liste, inklusive der Fehler, die wir gemacht haben.

Warum öffentlich ?

Odoo-Migrationsberichte gibt es reichlich als Verkaufsprospekt; aber nur selten als Protokoll. Uns hätte vor der Migration ein Text geholfen, der beschreibt, was nach dem erfolgreichen Upgrade-Lauf noch so zu tun ist. Darum schreiben wir ihn nun.

Zur Einordnung: Bei uns ist Odoo nicht nur „das ERP". Es ist gleichzeitig Firmenwebsite, öffentlicher Webshop mit Kauf- und Mietartikeln, Importvorgängen aus Online-Preislisten und Hersteller-Lizenzservern, Abo-Abrechnung, Angebots- und Rechnungswesen sowie die Steuerung unserer eigenen Lizenzausgabe.

Dazu 11 eigene beziehungsweise gepflegte Module und unzählige Anpassungen an Website-Templates. Diese Kombination ist der Grund, warum unsere Migration mehr Nacharbeit erzeugt hat als eine reine Backoffice-Installation — und warum die Befunde unten für Sie vermutlich relevanter sind als ein Standardfall.

Was der Upgrade-Service gut macht

Fairerweise zuerst das, was gut funktioniert hat. Der offizielle Upgrade-Service migriert von Version 17, über Version 18 als Zwischenstufe, auf die Version 19. Das läuft automatisch und war bei uns nach weniger als einer Stunde durch.

  • Die Datenmigration selbst war vollständig und korrekt. Keine verlorenen Aufträge, keine kaputten Rechnungen, keine Inkonsistenzen.

  • Der Report ist ausführlich und ehrlich. Er listet jede deaktivierte View, jede umbenannte Spalte und jede geänderte Steuer auf. Abern: Man muss ihn wirklich lesen — bei uns waren es mehrere Seiten.

  • Zurückgesetzte, angepasste Website-Views wurden als Backup-Kopie abgelegt. Das hat uns später mehrfach gerettet.

Der Testmodus (mit Neutralisierung von Mailversand und Cronjobs) ist die Grundlage für alles Weitere. Wir haben einen Tag vor dem Update ausschließlich auf dieser migrierten Kopie gearbeitet und jeden Befund gegen die noch laufende Produktivseite verglichen. Ohne diesen Tag wäre der Freitag ein Desaster geworden.

Alle beim Vergleich entdeckten Abweichungen flossen ganz ausführlich in eine Änderungsdokumentation ein.

Bruchstelle 1: Das Mobilfeld ist weg — und mit ihm Daten

Das ist der Befund, den jeder Odoo-Nutzer kennen sollte, weil er still passiert.

In Odoo 19 gibt es am Kontakt kein Feld mobile mehr. Die Spalte wurde entfernt. Das Verhalten des Upgrade-Service dabei: Die Mobilnummer wird nach phone übernommen — aber nur, wenn phone leer war. Bei jedem Kontakt, der sowohl eine Festnetz- als auch eine Mobilnummer hatte, wurde die Mobilnummer ersatzlos verworfen. In der Zieldatenbank gibt es keine Backup-Tabelle, aus der man sie zurückholen könnte.

Bei uns waren mehrere hundert Kontakte mit Mobilnummer betroffen. Bei 176 davon war die Nummer nach phone gewandert und hatte dort die eigentliche Festnetznummer verdrängt oder überschrieben. Rekonstruierbar war das nur, weil wir die alte v17-Datenbank nach dem Cutover noch parallel laufen ließen.

Es kommt ein zweiter Effekt hinzu, der noch leichter zu übersehen ist: Odoo gleicht Rufnummern intern über das Feld phone_sanitized ab — das nutzen SMS, WhatsApp, die Blacklist und die eingebaute VoIP-Funktion. In Version 17 flossen dort Festnetz- und Mobilnummer ein. In Version 19 nur noch phone. Wer also eine Telefonanlage oder ein SMS-Gateway an Odoo gekoppelt hat, verliert damit die Erkennung aller Anrufe von Mobilnummern — ohne dass irgendwo eine Fehlermeldung erscheint. Unser DirectoryHub und Reverse Lookup Pro für STARFACE – unsere Produkte zur Namensauflösung bei eingehenden Anrufen waren sofort betroffen. Mobilfunkrufnummern konnten nicht mehr aufgelöst werden.

Unsere Lösung: ein kleines eigenes Modul, das das Feld mobile wieder einführt, es in Formular, Unterformular und Listenansicht einblendet, es dem Telefon-Suchfilter hinzufügt und es wieder in die Rufnummernnormalisierung einhängt. Die Daten haben wir per SQL aus der alten Datenbank zurückgespielt und anschließend die Normalisierung einmalig neu berechnen lassen — direkte SQL-Updates lösen in Odoo keine Neuberechnung aus, das muss man von Hand anstoßen.

Was Sie daraus mitnehmen sollten: Prüfen Sie vor der Migration, wie viele Ihrer Kontakte eine Mobilnummer haben, und exportieren Sie diese Spalte separat. Und lassen Sie die alte Datenbank nach dem Umzug noch ein paar Wochen erreichbar.

Bruchstelle 2: Copy-on-Write-Views, der stille Killer

Wer den Odoo-Website-Editor benutzt, erzeugt dabei Kopien der zugrundeliegenden Templates — sogenannte COWed Views. Nach Jahren Betrieb sammeln sich davon hunderte an. Bei uns waren es 198 Stück.

Das erste Symptom nach dem Upgrade war banal und trotzdem verwirrend: Die Kopfzeile der Website rendert mit einer leeren CSS-Klasse. Kein Sticky-Header, keine Hover-Menüs. Ursache war eine byte-identische Kopie des Basis-Layouts. Beim Rendern dieser Kopie werden nämlich nur deren eigene Kind-Templates angewandt — alle Erweiterungen, die am Original hängen, fallen weg. Die Kopie war inhaltlich völlig identisch mit dem Original und hat trotzdem die halbe Seite zerlegt.

Zwei weitere Fallen im selben Themenkomplex:

  • Nach dem Aufräumen rendert der Standard-Header von Odoo 19 seine Demo-Telefonnummer. Die stand nie in Verbindung mit den Firmendaten, sondern ist hart kodiert im Template — und zwar mehrfach, sodass ein einzelner Override nicht reicht.

  • Beim Modul-Update legt Odoo automatisch Website-Kopien der eigenen Modul-Templates an. Diese Kopien frieren den Stand ein und blockieren damit alle künftigen Updates dieses Moduls — man ändert Code, deployt, und nichts passiert. Das gehört als fester Aufräumschritt in jedes Deployment.

Beim Aufräumen muss man allerdings genau zwei Sorten Kopien verschonen: alles, was zu einer echten Website-Seite gehört, und das Formular für Zusatzinformationen im Checkout. Löscht man die mit, verschwinden Startseite und Bestellformular. Wir haben deshalb alle Kopien vor dem Löschen in eine Backup-Tabelle geschrieben.

Bruchstelle 3: Einstellungen, die still verschwinden

Die Migration setzt Konfigurationsschalter zurück, ohne das im Report zu erwähnen. Bei uns betraf das zwei Haken in den Verkaufs- und Website-Einstellungen: „Rabatte" und „Vergleichspreis". Folge: Im gesamten Shop fehlten sämtliche durchgestrichenen Streichpreise. Wir haben lange in den Templates gesucht, bevor wir gemerkt haben, dass gar kein View-Problem vorlag.

Wichtig für die Planung: Der Produktiv-Migrationslauf leert diese Gruppen erneut. Was Sie auf dem Testsystem reparieren, müssen Sie nach dem Cutover ein zweites Mal reparieren. Solche Schritte gehören zwingend auf die Nacharbeitsliste, nicht ins Gedächtnis.

Weitere Dinge, die deaktiviert wurden und die man erst bemerkt, wenn sie fehlen:

  • Sämtliche Studio-Anpassungen an Kontakt-, Aufgaben-, Zahlungs- und Produktformularen.
  • Alle Views eines eingesetzten OCA-Vertragsmoduls.
  • Mehrere Steuersätze mit „inklusive"-Kennzeichnung — Odoo 19 regelt Brutto/Netto jetzt firmenweit anders.
  • Ein fehlerhafter Ausdruck in der Bilanz, den man von Hand reparieren muss, weil sich die Syntax für berichtsübergreifende Verweise geändert hat.

Bruchstelle 4: Der Shop rechnete falsch

Für alle mit Odoo-Webshop, besonders mit Abo- oder Varianten-Produkten. In Odoo 19 gehen an mehreren Stellen im website_sale-Pfad die variantenbezogenen Preisregeln verloren, wenn nur das Produkt-Template nachgeschlagen wird:

  • Produktkacheln zeigten „ab 0 €" statt eines tatsächlich günstigsten Variantenpreises.
  • Zubehör- und Alternativartikel zeigten nur den Listenpreis, nicht den Abopreis.
  • Das Karussell mit Alternativprodukten zeigte „0,00 €" — es benutzt einen völlig eigenen Datenpfad über die dynamischen Snippets.
  • Ein in Version 19 entferntes Text-Feld im Produktkachel-Template führte zu einem HTTP 500 — allerdings nur in Kategorien, die ein Produkt mit Preis 0 enthalten. Solche Fehler findet man nicht durch Klicken auf der Startseite.

Bruchstelle 5: Der Checkout-Schritt, der still verschwand

Das war der unangenehmste Fund. Unser Checkout hat einen eigenen Schritt, in dem Kunden Lizenzinformationen angeben. Nach der Migration war dieser Schritt weg — nicht defekt, nicht mit Fehlermeldung, sondern übersprungen. Odoo 19 blendet den Schritt für Zusatzinformationen kommentarlos aus, wenn das zugehörige Formular fehlt. Und das Formular war eine der Website-Kopien, die wir beim Aufräumen erwischt hatten.

Dazu kam, dass der Initialisierungscode unserer Module nur bei Neuinstallation läuft, nicht beim Update — ein zweiter, generischer Checkout-Schritt fehlte deshalb ebenfalls.

Die Lehre: Ein Smoke-Test nach der Migration darf nicht bei „Shop lädt" aufhören. Er muss einen vollständigen Testkauf mit allen Zwischenschritten und einer echten Bestellung umfassen. Ein stillschweigend übersprungener Pflichtschritt im Checkout kostet Geld, ohne eine einzige Zeile im Log zu erzeugen.

Was wir selbst falsch gemacht haben

Zwei Dinge, die vermeidbar gewesen wären:

Erstens haben wir während der Portierung zwei Repositories parallel gepflegt: eines für den v19-Port, eines für den produktiven Stand. Zwei Fehlerbehebungen sind dadurch nie auf dem Server angekommen und mussten Tage später einzeln nachgetragen werden. Ein Zweig, ein Ziel — das klingt trivial, geht aber unter Migrationsdruck als Erstes verloren.

Im Migrationsprozess haben wir uns dazu entschlossen, jede Änderung im git zu tracken – sehr gute Entscheidung und absolut empfehlenswert. Denn es gibt durchaus auch mal Regressionen.

Zweitens haben wir zu spät gemerkt, dass die Reihenfolge beim Deployment entscheidend ist: Der Dateispeicher muss vollständig an Ort und Stelle liegen, bevor der Modul-Update-Lauf startet — denn der schreibt selbst neue Dateien dorthin. In der falschen Reihenfolge produziert man sich stille Inkonsistenzen.

Unser Ablauf, falls Sie ihn übernehmen wollen

  1. Vollständiger Export von Datenbank und Dateispeicher.
  2. Upgrade-Service im Testmodus — die Kopie wird zum Übungsplatz, nicht die Produktion.
  3. Einen vollen Arbeitstag auf der Kopie, jeder Befund gegen die laufende Produktivseite verglichen und dokumentiert.
  4. Am Cutover-Tag: erneuter Export, Upgrade-Service im Produktivmodus (ohne Neutralisierung, sonst bleibt der Mailversand tot).
  5. Offline einspielen bei gestopptem Odoo, Dateispeicher zuerst.
  6. Vorbereitungs-SQL — bei uns: Views aufräumen, Kopien sichern und löschen, Inhalte gezielt zurückspielen. Alles in einer Transaktion, damit ein Fehlversuch sauber zurückrollt und das Skript beliebig wiederholbar bleibt.
  7. Ein einziger Modul-Update-Lauf über alle eigenen Module.
  8. Nacharbeiten aus der Liste: Konfigurationshaken, automatisch erzeugte Kopien löschen, fehlende Schritte anlegen.
  9. Kompletter Testkauf inklusive aller Checkout-Schritte und einer echten Bestellung.
  10. Erst dann umschalten.

Alles ab Schritt 6 haben wir als versioniertes SQL-Skript und als Runbook abgelegt, nicht als Notizzettel. Beim zweiten Durchlauf am Produktivsystem war das den Aufwand wert. Es mussten nur noch die Schritte aus dem Runbook abgearbeitet werden.

Zwei Dinge, die Sie jetzt schon einplanen sollten

Unabhängig vom Migrationszeitpunkt: XML-RPC und JSON-RPC sind ab Version 19 als veraltet markiert. Die Entfernung ist für die kommenden Hauptversionen angekündigt — nach heutigem Stand ab Winter 2027 beziehungsweise Herbst 2028. Wer Fremdsysteme über diese Schnittstellen an Odoo angebunden hat — Telefonanlage, Versanddienstleister, Shopsystem, DATEV-Brücke — sollte die Umstellung auf die neue JSON-2-API jetzt in die Planung nehmen und nicht erst, wenn sie erzwungen wird.

Und: self._context ist ab Version 19 veraltet. Bei uns hat das in einem Preismodul bei jedem Produktaufruf eine Warnung ins Log geschrieben. Vier Zeilen Änderung, aber vorher ein Logfile, in dem man nichts mehr fand.

Fazit

Der Odoo-Upgrade-Service macht seinen Teil der Arbeit zuverlässig — er migriert die Daten. Was er nicht macht, ist Ihre Website, Ihren Shop, Ihre Editor-Anpassungen und Ihre Integrationen wieder in den Zustand versetzen, in dem sie vorher waren. Der Aufwand steckt fast vollständig hinter dem grünen Haken, und er wächst mit jedem Jahr, in dem jemand den Website-Editor benutzt hat.

Wenn wir eine einzige Empfehlung geben dürften: Behalten Sie die alte Datenbank. Nicht als Dump im Archiv, sondern lauffähig und abfragbar. Alles, was wir in dieser Migration rekonstruieren konnten, konnten wir nur deshalb rekonstruieren.


Wenn Sie vor einer Migration stehen oder Odoo an Ihre Telefonie anbinden möchten, sprechen Sie uns an!

Insight Analytics 2026
Analyse- und Monitoring für STARFACE