Come migrare un database Odoo da una versione a un'altra

Una guida generale per aiutare sviluppatori e altri Odooers ad affrontare uno dei task più complicati e ricorrenti di ogni istanza Odoo: la migrazione di Odoo ad un'altra versione

La migrazione Odoo è un processo quasi inevitabile per chi vuole continuare ad avere un sistema Odoo aggiornato e al passo con i tempi, che continui ad essere supportato e che non abbia buchi di sicurezza.

Nel corso degli anni mi sono trovato ad affrontare innumerevoli migrazioni e per prima cosa posso dire che non esiste una metodologia realmente standard per la migrazione. O meglio, esistono una serie di strumenti e buone prassi che sono sicuramente fattor comune a tutte le migrazioni ma diverse decisioni, azioni e linee metodologiche sono differenti da istanza a istanza.

Ci sono alcune domande che accompagnano la fase iniziale di analisi quando si deve approcciare la migrazione: l'istanza Odoo è versione enteprise o community? L'istanza è su odoo.sh? Quanto è grande il database che si sta migrando? Dove sono concentrati la maggior parte dei dati? Quante integrazioni ci sono con i sistemi esterni e quanto questi sono dipendenti da Odoo? Quanto impatta il momentaneo spegnimento di Odoo sul business del cliente, e quanto tempo al massimo si può tenere spenta per il processo di migrazione? 

Sono quesiti in realtà che dovrebbero essere posti anche in fase di prima implementazione, per capire (ad esempio) quanto ha senso centralizzare alcuni processi in Odoo e quanto esternalizzarne ad altri software, ed evitare di dover affrontare problemi che prima o poi presenteranno il conto e che potrebbero addirittura far saltare il progetto.

Andiamo di seguito a vedere gli step classici che riguardano la maggir parte delle migrazioni Odoo.

Migrazione del database Odoo

Per la migrazione di un database Odoo da una versione a una superiore esistono principalmente due strumenti: il tool OCA di Openupgrade, o lo script ufficiale di Odoo SA messo a disposizione per i clienti Enterprise. Viene quindi da se che in caso di istanza base non enterprise si avrebbe a disposizione il solo tool Openupgrade. 

Spieghiamo di seguito le due procedure.

Come migrare un database Odoo usando Openuprade, il tool di OCA.

Openupgrade è uno strumento sviluppato dalla Odoo Community Association (OCA) che aiuta gli utenti a migrare i loro database da una versione di Odoo all'altra con facilità, è totalmente opensouce e il suo codice può essere visionato al seguente repository github: https://github.com/OCA/OpenUpgrade (mentre la documentazione ufficiale è acessibile al seguente link:  https://oca.github.io/OpenUpgrade/index.html).

Di seguito gli step necessari per effettuare la migrazione:

1. Per prima cosa è necessario clonare il repository all'interno del path Odoo della versione target a cui si vuole migrare. Poniamo il caso che vogliamo migrare a versione 16 e che Odoo sia all'interno del path /opt/odoo16/odoo, allora dovremo clonare il repository OpenUpgrade in quella cartella, dando come riferimento il branch 16.0:

cd /opt/odoo16/odoo
git clone https://github.com/OCA/OpenUpgrade -b 16.0

All'interno della cartella OpenUpgrade troveremo due cartelle principali: openupgrade_framework, che contiene le patch Odoo, e openupgrade_scripts che contiene le analisi e gli script di migrazione veri e propri.

2. Eseguire gli update contenuti nel file requirements.txt all'interno della folder principale di OpenUpgrade:

pip install -r requirements.txt

3. Lanciare lo script puntando al database che si desidera migrare e la versione target di Odoo. È buona prassi testare la migrazione più e più volte su un backup del database originale, fino a quanto la procedura non appare stabile. Lo script va lanciato all'interno della cartella root di Odoo, come se si stesse lanciando un'istanza. Se ad esempio abbiamo il nostro Odoo all'interno di /opt/odoo16/odoo il comando sarà:

python odoo-bin -d db_to_migrate --upgrade-path=/opt/odoo16/odoo/OpenUpgrade/openupgrade_scripts --update all --stop-after-init --load=base,web,openupgrade_framework

A questo punto la procedura di migrazione partirà e vedremo a schermo il log degli script in esecuzione. Bisogna ora tener conto che non sempre la migrazione riesce al primo colpo, sopratutto quando l'istanza è molto customizzata, ci sono tanti dati, o ci sono errori negli stessi. Qualora ci fossero degli errori bisognerà analizzare gli stessi e procedere ai fix, che il più delle volte sono fatti attraverso query al database. Per fare un esempio ci potrebbero essere delle constraint introdotte dopo solo certe versioni, e questo potrebbe portare ad errori se uno dei campi in questione ha valori non complaint a tale constraint. Sarà pertanto necessario agire sul record per renderlo compatibile.

L'altra strada, per errori più complessi, è di agire direttamente sugli script di OpenUpgrade per correggere l'errore in funzione del nostro database. In entrambi i casi, vista l'eterogeneità delle casistiche è obbligatorio affidarsi a professionisti Odoo qualificati in grado di comprendere e correggere l'errore.

Come migrare un database Odoo usando gli script di Odoo SA

L'altra soluzione, a disposizione per i soli clienti enterprise, è usare il tool messo a disposizione da Odoo SA. Questa la pagina ufficiale del tool: https://upgrade.odoo.com.

Per le istanze on-premise le soluzioni sono quelle di lanciare il processo tramite linea di comando, oppure quella di usare la form dove è possibile fare l'upload del dump del database e iniziare la migrazione direttamente da interfaccia grafica. La seconda soluzione è a disposizione per le istanze con database non troppo grandi, con massimo 2GB di spazio.

Per quanto concerne invece il tool da riga di comando andiamo a spiegare di seguito come usarlo.

Il comando di base, come riportato dalla stessa documentazione è questo:

python <(curl -s https://upgrade.odoo.com/upgrade) test -d <your db name> -t <target version>

L'istruzione python <(curl -s https://upgrade.odoo.com/upgrade) consente di far girare in locale le istruzioni python contenute nell'indirizzo web in questione. Test è la tipologia di migrazione che stiamo eseguendo, e che in caso di successo di restituirà un database totalmente neutralizzato da poter testare. L'istruzione -d deve essere seguita dal nome del database odoo da migrare presente nel nostro server postgres. Infine abbiamo -t che deve essere seguita dalla versione target a cui vogliamo portare il database (es: -t 17.0). Quando arriverà il momento di effettuare la migrazione per il sistema live vero e proprio il pametro 'test' dovrà essere sostituito da 'production', in modo da avere un database non neutralizzato utilizzabile in un'istanza di produzione.

Quando il comando viene eseguito viene generato un token che identificherà in maniera univoca la migrazione che stiamo effettuando e che potrà essere utilizzato per varie operazioni, come spiegheremo di seguito.

Oltre al comando per iniziare la migrazione vera e propria il tool di comando Odoo mette a disposizione diverse azioni, che possono essere elencate dando il comando:

python <(curl -s https://upgrade.odoo.com/upgrade) --help

Le opzioni restore, status e log servono rispettivamente a: scaricare un database migrato con successo dalla procedura; avere lo status di una specifica migrazione; accedere al log di una specifica migrazione. Per ognuno di questi argomenti possiamo utilizzare l'opzione --help per conoscere i parametri accettati da esso:

python <(curl -s https://upgrade.odoo.com/upgrade) log --help
usage: python <(curl -s https://upgrade.odoo.com/upgrade) log
       [-h] -t TOKEN [-f FROM_BYTE]

optional arguments:
  -h, --help            show this help message and exit
  -t TOKEN, --token TOKEN
                        The token ID of the request
  -f FROM_BYTE, --from-byte FROM_BYTE
                        From which line start retrieving the log (0=from the
                        beginning)

Nell'esempio sopra possiamo vedere la spiegazione su come usare l'argomento log. Come si può notare è fondamentale l'uso del token univoco generato in fase di lancio della migrazione (per tutte le tipologie sopra elencate).

python <(curl -s https://upgrade.odoo.com/upgrade) test --help
usage: python <(curl -s https://upgrade.odoo.com/upgrade) test
       [-h] [-d DBNAME] [-r RESTORE_NAME] [-i DUMP] [-c CONTRACT] -t TARGET
       [-e ENV] [--env-file ENV_FILE] [-x] [-s SSH_KEY] [-j CORE_COUNT]
       [-n DATA_SERVER_NAME] [-u DATA_SERVER_USER] [-p DATA_SERVER_PATH]

optional arguments:
  -h, --help            show this help message and exit
  -d DBNAME, --dbname DBNAME
                        The name of a database to dump and upgrade
  -r RESTORE_NAME, --restore-name RESTORE_NAME
                        The name of database into which the upgraded dump must
                        be restored
  -i DUMP, --dump DUMP  The database dump to upgrade (.sql, .dump, .sql.gz,
                        .zip or a psql dump directory with toc.dat file)
  -c CONTRACT, --contract CONTRACT
                        The contract number associated to the database (by
                        default taken from the DB if it already has one,
                        mandatory when sending a dump file with --dump)
  -t TARGET, --target TARGET
                        The upgraded database version
  -e ENV, --env ENV     Set an environment variable, in the format VAR=VAL
  --env-file ENV_FILE   Read in a file of environment variables, one per line,
                        in the format VAR=VAL
  -x, --no-restore      Download the upgraded database dump without restoring
                        it
  -s SSH_KEY, --ssh-key SSH_KEY
                        The ssh key to use for data transfer (default:
                        /tmp/1000_upgrade_ssh_key)
  -j CORE_COUNT, --core-count CORE_COUNT
                        The number of core to use to dump/restore a database
                        (default: 4)
  -n DATA_SERVER_NAME, --data-server-name DATA_SERVER_NAME
                        The server name where to download/upload dumps
                        (default: upgrade.odoo.com)
  -u DATA_SERVER_USER, --data-server-user DATA_SERVER_USER
                        The server user where to download/upload dumps
                        (default: odoo)
  -p DATA_SERVER_PATH, --data-server-path DATA_SERVER_PATH
                        The path on the server where to download/upload dumps
                        (default: /data)

Vediamo sopra invece le opzioni a disposizione per la procedura di migrazione di test e produzione. Ci sono diverse opzioni interessanti, come ad esempio la possibilità di usare un dump di un database anziché un database restorato e presente in postgres, chiamando l'opzione -i anziché l'opzione -d. Si possono poi indicare in maniera dettagliata il numero di core da utilizzare per il processo di dump attraverso l'opzione -j, oppure usare l'opzione -x per evitare che al termine di una migrazione terminata con successo il tool di Odoo SA finisca con non solo a restituire il dump ma a fare il restore nel vostro server poster.

In definitiva, possiamo vedere come il tool sia molto flessibile e possa essere adattato alle nostre esigenze specifiche. Facciamo infine notare che la procedura è asincrona, pertanto una volta che il database è stato inviato ai server Odoo SA possiamo spegnere la nostra macchina e seguire la procedura quando e dove vogliamo, usando il token della migrazione.

In caso di errore possiamo provare a gestire e fixare lo stesso attraverso qualche query del nostro database. Se questo non fosse sufficiente allora dovremo necessariamente aprire un ticket al servizio di assistenza tecnico di Odoo, indicando la licenza dell'istanza: a differenza di OpenUpgrade il tool è proprietario e solo i tecnici di Odoo SA possono modificare lo script per la casistica specifica della nostra istanza.

Ripristinare il filestore Odoo

Le procedure sopra elencate sono per migrare il database a una nuova versione, ma non include la migrazione del filestore. Di default Odoo genera un filestore per ogni suo specifico database nella cartella standard ~/.local/share/Odoo/filestore, a meno che non sia dichiarato diversamente nel file di configurazione di Odoo.

Ripristinare il filestore per una migrazione è in realtà un'operazione molto semplice. Facciamo di seguito un esempio pratico. Poniamo che il caso che il database della nostra istanza Odoo sia per versione 14 e si chiami odoo_14, e abbiamo migrato un database a versione 16 rinominandolo odoo_16.

Nella cartella /.local/share/Odoo/filestore avremo sicuramente la sottocartella odoo_14, che conterrà tutta la struttura filestore della nostra istanza 14. Nel caso avessimo lanciato l'istanza 16 prima di ripristinare il filestore avremo già una sottocartella denominata odoo_16 (non è una cosa che compromette il ripristino del filestore, ma se volete testare o migrare un'istanza con tanto di filestore consigliamo di mettere questo nella giusta location prima di lanciare l'istanza).

In questo caso basterà copiare il filestore odoo_14 dando come destinazione di cartella odoo_16, quindi su linux daremo il comando:

cp -r odoo_14 odoo_16

Migrazione di moduli e codice personalizzato

Ovviamente l'altro aspetto da considerare nel corso di una magrazione è relativo ai moduli installati nel sistema. Per prima cosa occorre fare una mappatura per capire, al di là di moduli core e Enterprise installati, quanti moduli OCA utilizziamo, se abbiamo acquistato moduli terze parti e se eventualmente abbiamo uno o più moduli personalizzati.

Moduli core e Enterprise generalmente sono esclusi dall'analisi nel processo di migrazione in quanto questi sono già migrati, ma è ad ogni modo buona prassi avere un'idea di cosa è cambiato a livello strutturale e funzionale perché diversi cambiamenti potrebbero avere un impatto non poco trascurabile sui nostri moduli custom. Pensiamo ad esempio a quando, in Odoo versione 13, la classe account.invoice è stata del tutto eliminata per avere tutto dentro account.move.

Se utilizziamo uno o più moduli OCA dobbiamo controllare che questi siano stati migrati correttamente. Solitamente all'interno della sezione Issue del repository troviamo pagine dedicate alla migrazione di una specifica versione: vedere ad esempio la pagina di account-invoicing per la migrazione del codice a versione 16 https://github.com/OCA/account-invoicing/issues/1250

Relativamente a moduli e repository OCA occorre fare alcune considerazioni. Anche se l'OCA è un'organizzazione con sue regole specifiche diversi repository sono gestiti dalle associazioni OCA locali, che possono prendere decisioni specifiche in merito alla gestione di un dato repository. Ad esempio il repository della localizzazione italiana (https://github.com/OCA/l10n-italy) è migrato con tutte le funzionalità solo per le versioni pari, in quanto è diventato troppo oneroso migrare il codice ad ogni nuova versione Odoo (rilasciata tendenzialmente ogni anno).

In linea generale quando viene rilasciata una nuova versione Odoo è improbabile che i moduli OCA siano già stati convertiti o che la conversione si concluda nel giro di pochi mesi. Ad ogni modo, si tenga presente che i repository e l'associazione OCA sono governati da sani principi che contraddinstinguono le community OpenSource. Pertanto se non doveste trovare qualcosa di convertito e questo vi serve a breve, l'invito è quello di collaborare (https://odoo-community.org/get-involved/contribute) in maniera attiva e proporsi per la conversione del modulo o eventualmente aiutare per quelli già in corso.

Per quanto concerne invece i moduli terze parti bisogna andare sul webstore Odoo per controllare che questi siano stati convertiti alla nostra versione target, e in caso positivo acquistare nuovamente il modulo. Qualora il modulo non fosse presente si invita a contattare la casa sviluppatrice. Se anche questo tentativo non andasse a buon fine dovremo sviluppare un nostro modulo per riportare la funzionalità che precedentemente era messa a disposizione dal modulo terze parti.

Infine occorrerà migrare i nostri moduli personalizzati per renderli compatibili alla versione target. In questo caso possiamo dare alcuni consigli generici che sono validi per ogni migrazione.

Per prima cosa controllate quali sono le principali differenze tecniche tra le due versioni, in modo da adattare con successo il vostro codice: per fare un esempio dalla versione 13 i decorator @api.one e @api.multi non sono più utilizzati. Alcune innovazioni vengono riportate nel changelog della documentazione Odoo (https://github.com/odoo/documentation/blob/17.0/content/developer/reference/backend/orm/changelog.rs)) ma riteniamo che questa non rappresenti in maniera esaustiva tutti i cambiamenti tecnici avvenuti in una specifica versione.

Infine occorrerà migrare i nostri moduli personalizzati per renderli compatibili alla versione target. In questo caso possiamo dare alcuni consigli generici che sono validi per ogni migrazione.

Risoluzione di problemi comuni 

Avete migrato il database e il codice, avete tutti i moduli pronti e a questo punto volete testare l'istanza Odoo alla nuova versione. A questo punto però vi rendete conto che qualcosa ancora non va e ci sono errori bloccati su una o più viste nel sistema, oppure si sono problemi a livello di assets. Il primo consiglio è quello di eliminare gli assets dal sistema e rigenerarli, cosa che si può fare con una query del genere:

delete from ir_assets;

Non dovete farlo necessariamente per tutti gli assets. A volte capita che in una nuova versione alcuni moduli non siano più utilizzati, ed è quindi necessario rimuovere ogni traccia di esso che possa provocare conflitti. Per eliminare assets collegati ad uno specifico modulo la query diventa:

delete from ir_asset where path ilike '%your_module%';

Se notate che tale modulo continui a dare problemi, se non viene più usato conviene portarlo in stato non installato:

update ir_module_module set state='uninstalled' where name='your_module'; 

Occorre poi eleminare le eventuali viste personalizzate del modulo:

delete from ir_ui_view where arch_fs ilike '%your_module%';

Qualora invece aprendo qualche vista otterreste degli errori del tipo campo mancante è perché c'è ancora qualche vista nella quale ci sono uno o più campi che non sono più presenti nel nuovo database.

delete from ir_ui_view where cast(arch_db as text) like '%missing_fields%';

Continuate a questo punto a testare un po' tutte le viste e ripetere la procedura fino a quando non arrivate ad avere un sistema stabile.

Qualora aveste problemi specifici o altre considerazioni da fare vi invitiamo a riportare i vostri commenti o a scriverci direttamente via email.

in Odoo
Come migrare un database Odoo da una versione a un'altra
Raffaele Del Gatto 1 giugno 2024
Condividi articolo
Etichette
Archivio
Accedi per lasciare un commento
Odoo: come modificare un external layout solo per alcuni report