Frankhood Lorem ipsum dolor sit amet, consectetur adipisicing elit. Frankhood Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ai and Machine Learning Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cloud Service Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Digital Marketing Solutions Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mobile Development Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Project and Product Management Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quality Assurance Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Strategic Consulting Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Web Development Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Approach Identify Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Approach Improve Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Approach Support Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Approach Tailor Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Approach Understand Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Planet Dotted Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Planet Striped Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Planet Solid Icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Bullet Quote Pink icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Bullet Quote Green icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Bullet Quote Blue icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Bullet Quote Purple icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Bullet Quote Yellow icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Finance icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Retail icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Industry icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Health Care icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Marketing icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ai Deep Learning icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ai Computer Vision icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ai Nlp icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ai Predictive icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ai Data Visualization icon Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ai Decision Support System icon Lorem ipsum dolor sit amet, consectetur adipisicing elit.
, Nicola Ciccarone

Migrazione da Python 2.7 Django 1.8 a Python 3.6 Django 2.2

PRIMO SEMESTRE 2020

Migrazione da Python 2.7 Django 1.8 a Python 3.6 Django 2.2

L’attività di migrazione è stata pensata per svecchiare un grosso progetto che utilizzava tecnologie obsolete e in via di superamento. Quando un progetto continua ad evolversi per anni, con nuove funzionalità e sviluppi, si rende necessaria l’attività di migrazione.

L’attività di migrazione è stata pensata per svecchiare un grosso progetto che utilizzava tecnologie obsolete e in via di superamento. Il progetto continuava e continua tuttora ad evolversi, con nuove funzionalità e sviluppi, per questo è stata necessaria l’attività di migrazione.
Le tecnologie che utilizzava la web-application erano python 2.7 e django 1.8.

La necessità di aggiornare la versione di python nasce dal fatto che qualche tempo fa il team di sviluppo di Python aveva annunciato che il ramo 2.X del linguaggio di programmazione avrebbe smesso di essere supportato e aggiornato il primo gennaio 2020. Il ciclo di vita di Python 2 stava dunque per volgere al termine.

Anche se la prima versione di Python 3 risale al dicembre del 2008 e quindi i vari progetti software basati su Python 2 hanno avuto 10 anni di tempo per vedere aggiornata la propria codebase, il principale problema della migrazione a Python 3 sta nell’assenza di retrocompatibilità con le precedenti release. Questo elemento ha dunque portato diversi sviluppatori a rimandare a tempo indefinito il porting al ramo principale più recente; ed è il caso anche del nostro progetto in questione.

Stesso discorso è stato fatto con la versione di django utilizzata; infatti il supporto per la versione 1.8 finiva il 1 Aprile 2018.

Dunque la mia scelta è stata quella di effettuare prima la migrazione da python 2.7 a python 3.6 e poi quella da django 1.8 a django 2.2. 

Per prima cosa ho cancellato il virtualenv e l’ho ricreato utilizzando la versione 3.6 di python, concentrandomi poi sugli errori di compilazione. Di seguito alcuni degli errori che ho riscontrato e risolto per l’upgrade del mio progetto: 

  • Unicode: in Python 2 ci sono due varianti di stringa: quelle fatte di byte con tipo ( str ) e quelle fatte di testo con tipo ( unicode ). Un oggetto di tipo str è sempre una sequenza di byte, ma è comunemente usato sia per i dati di testo che per quelli binari.

In Python 3, tutte le stringhe sono considerate UNICODE di default. Il tipo unicode del Python 2 è stato rinominato in str in Python 3, e str è diventato bytes.

Dunque le operazione di retrocompatibilità che ho dovuto effettuare sono state:

- aggiungere l’import from __future__ import unicode_literals in tutti i moduli

- rimozione del prefisso ‘u’ che precedevano le stringhe

- aggiunta del prefisso ‘b’ sulle bytestring

- nelle classi modello che ereditano da django.db.models.Model, sostituzione del metodo __unicode__() con __str__()


  • Sostituzione di xrange con range

    - in Python 2.x range crea una lista, quindi ad esempio 

    range(1, 10000000)

     crea una lista in memoria con 9999999 elements. 

    xrange invece è una sequenza di oggetti che vengono valutati in maniera lazy, quindi è più performante.

    - In Python 3, la firma xrange non esiste più, ma range è l’equivalente di xrange di python 2. Se si vuole la lista (e quindi l’esatto comportamento di xrange) bisogna usare il metodo list

    list(range(1, 10000000))


    • Il tipo di dato dizionario non contiene più il metodo has_key. Quindi le istruzione del tipo 

    <dict>.has_key('<key>')  

    diventano 

    '<key>' in <dict>

    Sicuramente, possiamo dire che la migrazione più complicata, dovuta ai tanti errori di retrocompatibilità, è l’aggiornamento di django. Come nella precedente migrazione ho cercato di risolvere gli errori di compilazione, prima quelli a compile time e poi quelli a runtime. Dunque ho tentato per prima cosa di far partire il progetto, e dopo ho cercato di risolvere gli errori a runtime tramite il testing&tuning. 

    Alcuni degli errori più comuni di questa migrazione django sono stati:

    • l’obbligo di definire nelle foreign-key e nei one-to-one fields dei modelli, l’ on_delete. Bisogna ricordarsi di fare la stessa modifica anche nelle migrazioni
    • django.core.urlresolvers è stato sostituito da django.urls
    •  il sistema di routing con namespace richiede l’ app_name. Ciò significa che my_app.urls deve definire l’appname in questo modo: 
    • Nei settigs la variabile globale MIDDLEWARE_CLASSES va sostituita con MIDDLEWARE
    • django.conf.urls.patterns() è stato rimosso in django 1.10
    • is_authenticated() e is_anonymous() non sono più disponibili per l'oggetto Utenti; queste due funzioni sono diventate proprietà del modello, il che significa che ora è possibile accedervi senza parentesi:

    user.is_authenticated () → user.is_authenticated

    user.is_anonymous () → user.is_anonymous

    Questo è stato introdotto in Django 1.10 e i metodi erano ancora disponibili fino alla 1.11 per compatibilità con le versioni precedenti.

    Non basterebbe questo articolo per elencare tutti gli errori di compilazione. In linea di massima per la loro risoluzione ho seguito le linee guida sul sito di Django dove per ogni nuova versione del framework, viene rilasciato un documento con le nuove feature, quelle deprecate e quelle rimosse. 

    Dato che la nostra migrazione però, salta da django 1.8 a django 2.2 ho dovuto dare uno sguardo i documenti delle versioni intermedie:

    Altra operazione indispensabile in un’attività di ringiovanimento di un’applicazione web è l’aggiornamento delle dipendenze, anche quelle che continuano a funzionare con le versioni precedenti. Quindi, quello che consiglio è di esaminare prima l'elenco dei pacchetti e aggiornarli uno per uno, quindi eseguire i test e assicurarsi che si stia ancora comportando correttamente.

    Ovviamente si può iniziare a riparare le librerie, ma questa è una soluzione che sconsiglierei, poiché non risolverà davvero il problema per le applicazioni future.

    L'approccio migliore sarebbe quello di trovare il repository dei pacchetti, effettuare l’aggiornamento della libreria; se questa non viene aggiornata da tempo e quindi continua a non funzionare,  su Github si può creare un fork, in cui è possibile eseguire tutte le modifiche necessarie per far funzionare l'applicazione con Django 2.0. Il prossimo passo sarebbe fare una richiesta pull con questa patch e in un mondo ideale, dovresti quindi utilizzare la nuova versione del pacchetto. Se ciò non accade, rimangono alcune opzioni:

    • Trovare una libreria sostitutiva che viene aggiornato attivamente, che si adatta allo scopo.
    • Utilizzare temporaneamente il fork nei requirements finché la pull-request non viene mergeata.
    • Rilasciare un nuovo pacchetto mantenendo il fork (assicurarsi di rispettare i termini della licenza). In questo modo chiunque avesse il nostro stesso problema potrà risolverlo riutilizzando la nostra libreria.