2011-01-20 12 views
5

Zbudowałem aplikację appengine (python), która musi konwertować istniejące jednostki datastore w wartość całkowitą (100), aby wartość zmiennoprzecinkowa (100,00) dla problemu konwersji waluty. Jak to działa w odpowiedni sposób? Ponieważ moje zapytanie zwraca błąd, gdy po prostu zmienić typ właściwości w moim modelu.Zmiana IntegerProperty na FloatProperty istniejącego AppEngine DataStore

Old Model:

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) 

New Model:

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) 

muszę właściwą drogę do zmiany tego typu nieruchomości magazyn danych bez zmiany (usuwanie starych i dodać nowy) istniejące dane . Ponieważ jest to klucz używany w wielu innych tabelach/modelach.

Dzięki.

Odpowiedz

12

Najprostszym sposobem na to jest zmiana modelu na dziedziczenie z db.Expando i usunięcie właściwości liczb całkowitych z definicji. Następnie załaduj każde wystąpienie i wykonaj polecenie "instance.foo = float (instance.foo)" na każdym z nich, zanim zapiszesz je ponownie w magazynie danych - prawdopodobnie będziesz chciał użyć do tego interfejsu API mapreduce. Na koniec spraw, aby model ponownie rozszerzył db.Model, a następnie dodaj właściwość FloatProperties.

Naprawdę, naprawdę nie chcesz używać pływaka do waluty, chociaż: pływaki są podatne na błędy zaokrąglania, co oznacza, że ​​możesz stracić (lub zyskać!) Pieniądze. Zamiast tego należy użyć właściwości IntegerProperty, która zlicza liczbę centów.

+0

Jeszcze raz dziękuję Nick, biorąc pod uwagę liczbę całkowitą + centy dla tabeli walut. –

+2

@Ivan Nie miałem na myśli dwóch liczb całkowitych - choć to też by działało - po prostu chciałem zapisać całkowitą liczbę centów w jednym polu. Np. 10,23 USD jest przechowywane jako 1023. –

0

Może dobrym sposobem jest tymczasowy utworzyć nowy model:

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) 

następnie napisać jakiś skrypt, zadania lub widoku, które przekształcają instancji od starego modelu do czasowego modelu konwersji wartości całkowitych unosić. Upewnij się, że skopiowałeś identyfikator i klucz, jeśli to możliwe.

Po zmianie modelu głównego i skopiuj wszystkie wpisy z tymczasowego do niego. Następnie usuń tymczasowy model.

To najprawdopodobniej nie jest optymalny sposób i wymaga ręcznej migracji, ale bez południa i silnika aplikacji naprawdę nie widzę dobrego sposobu, aby to zrobić.

+0

Dzięki Torsten. –

-1

Na stronie Edit podmiotem w panelu administratora sklepu dane:

Wprowadź informacje dla podmiotu poniżej.Jeśli chcesz zmienić typ A m.in., ustawić go na null, zapisz podmiot, ponownie edytować jednostki, a zmienić typ

6

Oto exampe dla Nick Johnson „s 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() 
Powiązane problemy