2011-01-20 6 views
5

Ho creato un'applicazione appengine (python) che ha bisogno di convertire le entità del datastore esistenti in valore intero (100) in valore float (100.00) per il problema di conversione valuta. Com'è il modo giusto di fare questo? Dato che la mia query restituisce un errore quando cambio il tipo di proprietà nel mio modello.Modifica proprietà integer per FloatProprietà di AppEngine DataStore esistente

Vecchio modello:

class Learn(search.SearchableModel): 
    pid = db.ReferenceProperty(Product, collection_name='picks') 
    title = db.StringProperty() 
    description = db.TextProperty() 
    order = db.IntegerProperty() 
    cost = db.IntegerProperty(default=0) 
    cost1 = db.IntegerProperty(default=0) 

Nuovo Modello:

class Learn(search.SearchableModel): 
    pid = db.ReferenceProperty(Product, collection_name='picks') 
    title = db.StringProperty() 
    description = db.TextProperty() 
    order = db.IntegerProperty() 
    cost = db.FloatProperty(default=0.000) 
    cost1 = db.FloatProperty(default=0.000) 

ho bisogno di un modo corretto per modificare questo tipo di proprietà datastore senza cambiare (cancellare la vecchia e aggiungere nuovo) i dati esistenti . Dal momento che è la chiave utilizzata in molti altri tavolo/modello.

Grazie.

risposta

12

Il modo più semplice per eseguire questa operazione è modificare il modello da ereditare da db.Expando ed eliminare le proprietà integer dalla definizione. Quindi, carica ogni istanza e fai "instance.foo = float (instance.foo)" su ciascuno, prima di salvarli nuovamente nell'archivio dati. Probabilmente vorrai utilizzare l'API mapreduce per questo. Infine, fai in modo che il modello estenda nuovamente db.Model e aggiunga le proprietà Float.

In realtà, davvero non si vuole usare un flottante per valuta, però: i galleggianti sono soggetti a errori di arrotondamento, il che significa che puoi perdere (o guadagnare!) Denaro. Invece, utilizzare una proprietà Integer che conta il numero di centesimi.

+0

Grazie ancora Nick, considerando il numero intero + cent per la tabella delle valute. –

+2

@Ivan Non intendevo due numeri interi, anche se ciò avrebbe funzionato, intendevo solo memorizzare il numero totale di centesimi in un singolo campo. Ad esempio, $ 10,23 viene memorizzato come 1023. –

0

Forse un buon modo è quello di temporanea creare un nuovo modello:

class LearnTemp(search.SearchableModel): 
    pid = db.ReferenceProperty(Product, collection_name='picks') 
    title = db.StringProperty() 
    description = db.TextProperty() 
    order = db.IntegerProperty() 
    order = db.IntegerProperty() 
    cost = db.FloatProperty(default=0.000) 
    cost1 = db.FloatProperty(default=0.000) 

poi scrivere alcuni script, compito o vista che convertono le istanze dal vecchio modello a modello temporanea, convertendo i valori interi a stare a galla. Assicurati di copiare anche l'id e la chiave se in qualche modo possibile.

Dopo aver modificato il modello principale e aver copiato tutte le voci da quello temporaneo. Quindi rimuovere il modello temporaneo.

Questo probabilmente non è il modo ottimale e richiede una migrazione manuale, anche se senza South e sul motore dell'app non vedo davvero un buon modo per farlo.

+0

Grazie Torsten. –

-1

Dalla pagina Modifica entità nella interfaccia di amministrazione archivio dati:

Inserire le informazioni per l'entità di seguito.Se vuoi cambiare il tipo di una proprietà , impostarla su Null, salvare l'entità, modificare nuovamente l'entità, e cambiare il tipo di

6

Ecco exampe per s Nick Johnson' answer:

Before:

class Person(db.Model): 
    name = db.StringProperty() 
    age = db.StringProperty() #this will go to int 

After

class Person(db.Expando): 
    pass 

for person in Person.all(): 
    person.age = int(person.age) 
    person.put() 

Very after:

class Person(db.Model): 
    name = db.StringProperty() 
    age = db.IntegerProperty() 
Problemi correlati