2011-10-06 9 views
6

Quando si aggiorna un'applicazione GAE, qual è il modo migliore per aggiornare il modello dati?Transizione dati su più versioni dell'applicazione

Il numero di versione dell'applicazione consente di separare più versioni, ma queste versioni dell'applicazione utilizzano lo stesso archivio dati (in base a How to change application after deployed into Google App Engine?). Quindi cosa succede quando carico una versione dell'applicazione con un modello di dati diverso (sto pensando a Python qui, ma la domanda dovrebbe essere valida anche per Java)? Immagino che non dovrebbe essere un problema se le modifiche aggiungono un campo nullable e alcune nuove classi, quindi il modello esistente può essere esteso senza danno. Ma cosa succede se i cambiamenti del modello dati sono più profondi? Devo effettivamente perdere i dati esistenti se diventa incoerente con il nuovo modello di dati?

L'unica opzione che vedo per il momento sta mettendo l'archivio dati in modalità di sola lettura di manutenzione, trasformando i dati offline e distribuendo di nuovo l'intero.

risposta

6

Ci sono pochi modi di trattare con quello e non si escludono a vicenda:

  • fare un cambiamento non-rottura al vostro datastore e di lavoro intorno ai problemi che crea. Inserimento di nuovi campi in classi di modelli esistenti, passaggio di campi da obbligatorio a facoltativo, aggiunta di nuovi modelli, ecc. Questi non interromperanno la compatibilità con le entità esistenti. Ma dal momento che queste entità non cambiano magicamente per conformarsi al nuovo modello (ricorda che il datastore è un DB senza schema), potrebbe essere necessario un codice legacy che supporterà parzialmente il vecchio modello. Ad esempio, se è stato aggiunto un nuovo campo, sarà necessario accedervi tramite getattr(entity, "field_name", default_value) anziché entity.field_name in modo che non risulti in AttributeError per le vecchie entità.
  • Converti gradualmente le entità in un nuovo formato. Questo è abbastanza semplice: se trovi un'entità che utilizza ancora il vecchio modello, apporta le modifiche appropriate. Nell'esempio di cui sopra, si vorrebbe mettere il soggetto torna con nuovo campo viene aggiunto:

    if not hasattr(entity, "field_name"): 
        entity.field_name = default_value 
        entity.put() 
    val = entity.field_name # no getattr'ing needed now 
    

    Idealmente, tutte le entità saranno eventualmente trattati nel modo e si sarà in grado di rimuovere il codice di conversione ad un certo punto. In realtà, ci saranno sempre degli avanzi che dovrebbero essere convertiti manualmente - e questo ci porterà all'opzione numero tre ...

  • Converti in batch le tue entità in un nuovo formato. La complessità della logistica alla base di questo dipende molto dal numero di entità da elaborare, dall'attività del tuo sito, dalle risorse che puoi dedicare al processo, ecc. Si noti che l'utilizzo di MapReduce semplice potrebbe non essere l'idea migliore, specialmente se si utilizza la conversione graduale tecnica sopra descritta. Ciò è dovuto al fatto che i processi MapReduce sono tutte le entità di tipo determinato (recuperandole) mentre potrebbe esserci solo una piccola percentuale che ne ha bisogno. Quindi potrebbe essere utile codificare a mano il codice di conversione, scrivendo esplicitamente la query per le vecchie entità e ad es. utilizzando una libreria come ndb.