2011-01-20 15 views
5

Creé una aplicación appengine (python) que necesita convertir las entidades de almacén de datos existentes en un valor entero (100) en valor flotante (100.00) para el problema de conversión de moneda. ¿Cómo está la manera correcta de hacer esto? Dado que mi consulta devuelve un error cuando solo cambio el tipo de propiedad en mi modelo.Cambiar IntegerProperty a FloatProperty de AppEngine DataStore existente

Antiguo Modelo:

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) 

Nuevo Modelo:

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) 

necesito una manera apropiada para alterar este tipo de propiedad almacén de datos sin cambiar (eliminar edad y añadir nueva) los datos existentes . Dado que es la clave utilizada en muchos otros mesa/modelo.

Gracias.

Respuesta

12

La manera más fácil de hacerlo es cambiar el modelo para heredar de db.Expando y eliminar las propiedades enteras de la definición. Luego, cargue cada instancia y haga "instance.foo = float (instance.foo)" en cada una de ellas, antes de guardarlas de nuevo en el almacén de datos; probablemente querrá usar la API de mapreduce para esto. Finalmente, haga que el modelo extienda db.Model de nuevo y agregue FloatProperties nuevamente.

Sin embargo, realmente no desea utilizar un flotador para la divisa: las carrozas son susceptibles a errores de redondeo, lo que significa que puede perder (¡o ganar!) Dinero. En su lugar, use una IntegerProperty que cuente la cantidad de centavos.

+0

Gracias de nuevo Nick, considerando un número entero + centavos para la tabla de monedas. –

+2

@Ivan No me refería a dos enteros, aunque eso también funcionaría, solo me refería a almacenar el número total de centavos en un solo campo. Por ejemplo, $ 10.23 se almacena como 1023. –

0

Tal vez una buena manera de hacerlo es temporal crear un nuevo modelo:

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) 

luego escribir una secuencia de comandos, tarea o vista que convierten instancias de modelo antiguo con el modelo temporal, la conversión de los valores enteros a flotar. Asegúrate de copiar los ID y las claves también si de alguna manera es posible.

Después de cambiar su modelo principal y copiar todas las entradas de la temporal a la misma. A continuación, elimine el modelo temporal.

Probablemente esta no sea la forma óptima y requiera un poco de migración manual, aunque sin South y en el motor de aplicación realmente no veo una buena manera de hacerlo.

+0

Gracias Torsten. –

-1

Desde la página de edición de la entidad en la interfaz de administración de almacenamiento de datos:

introducir los datos de la entidad a continuación.Si desea cambiar el tipo de un de propiedad, establecen a NULL, salvo la entidad, editar la entidad de nuevo, y cambiar el tipo

6

Aquí es exampe para 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() 
Cuestiones relacionadas