debug_mode=ON

Buscar en

 
 

Acceder al datastore de App Engine con remote_api

Escrito por gimenete hace 1 años bajo una licencia de Creative Commons Creative Commons License
1254 visitas. Etiquetas: gae, google-app-engine, remote-api, app-engine

Google ha puesto a disposición de los usuarios de Google App Engine un script para ejecutar código de forma remota. Este script se denomina remote_api. Una de las principales utilidades es importar o exportar datos del datastore de nuestras aplicaciones.

Instalar el script remote_api

Lo primero que se debe hacer es modificar el fichero app.yaml añadiendo el script remote_api.py en la sección de handlers.

handlers:
- url: /remote_api
 script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
 login: admin

En este caso el script está configurado para ser accedido por la url /remote_api y se require autorización por parte de una cuenta de administrador.

Conectarse al remote_api

Basándome en un script del blog Bill Katz he creado una plantilla para para crear scripts que usen el remote_api.

#!/usr/bin/env python
#
import os
import sys
from google.appengine.ext import db
from google.appengine.ext.remote_api import remote_api_stub
import getpass

appengine_dirs = ['/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/']
sys.path.extend(appengine_dirs)
my_root_dir = os.path.abspath(os.path.dirname('/Users/gimenete/projects/myproject/'))
sys.path.insert(0, my_root_dir)
APP_NAME = 'nombre_aplicacion'
os.environ['AUTH_DOMAIN'] = 'gmail.com'

def auth_func():
    return (raw_input('Username:'), getpass.getpass('Password:'))

# Use local dev server by passing in as parameter:
# servername='localhost:8080'
# Otherwise, remote_api assumes you are targeting APP_NAME.appspot.com
remote_api_stub.ConfigureRemoteDatastore(APP_NAME, '/remote_api', auth_func)

La variable appengine_dirs deberá ser modificada según el directorio de instalación del Google App Engine SDK. Y la variable myrootdir debería apuntar al directorio donde se encuentr el código de nuestro proyecto.

El script nos pedirá un nombre de usuario y contraseña para auntenticarse. Se puede modificar la función auth_func() para que esto no sea así. Se pueden meter hardcoded el usuario y contraseña, leerlos de un fichero, etc.

Obtener y manipular los objetos del modelo

Con el código anterior el script ya ha sido configurado para conectarse al remote_api. A partir de ahí ya se pueden realizar consultas o modificaciones del datastore. El datastore ya se puede utilizar como si el código estuviera desplegado en los servidores de Google App Engine.

Una de las principales consultas que probablemente haremos es iterar TODOS los objetos de una clase. Esto tiene dos problemas:

  • App Engine limita las consultas a 1000 elementos
  • El offset en una consulta no puede ser mayor de 1000.

No obstante estos problemas se pueden esquivar. La solución consiste en obtener N objetos y luego hacer una consulta sobre los siguientes objetos que tengan una key() mayor que la del último elemento leído. Hay que tener en cuenta que esto no nos asegura que estemos obteniendo los objetos en el orden cronológico en el que se insertaron. Esta técnica está explicada en un artículo al respecto.

A continuación muestro una forma genérica de iterar todos los elementos de un tipo:

import model

def iterate(kind, func, max=100):
    entities = kind.all().fetch(max)
    while entities:
        for entity in entities:
            func.__call__(entity)
        entities = kind.all().filter('__key__ >', entity.key()).fetch(max)

def process_item(item):
    print author_key
    print item.title

print 'Items'

iterate(model.Item, process_item)

Navegar por el grafo de objetos

Otra importante cuestión al trabajar con el datastore, tanto en remoto como en los controladores de nuestra web, es la navegación por las relaciones de los objetos. Si por ejemplo queremos acceder a la propiedad "author" de un objeto "model.Item", podríamos hacer lo siguiente.

author = item.author

Sin embargo si la propiedad "author" es una relación (una propiedad de tipo ReferenceProperty), acceder a ella provoca una nueva consulta al datastore. Si iteramos N items y en cada iteración accedemos a la propiedad "author", estaremos haciendo N+1 peticiones. Esto ralentiza de forma muy sensible el rendimiento de nuestro script. Este problema también ocurre aunque sólo accedamos a la key() de la referencia.

key = item.author.key()

Existe otro método para evitar tener que cargar todo el objeto solamente para obtener su key()

key = model.Item.author.get_value_for_datastore(item)

Obteniendo las keys de esta forma y no de la anterior obtendremos una mejora de rendimiento notable. Recientemente en debugmodeon hicimos un script para migrar la base de datos. El script inicial tardaba aproximadamente dos horas en descargar todo el datastore a una base de datos MySQL. Al refactorizar el script utilizando getvaluefor_datastore el script pasó a tardar solamente 8 minutos.

Para terminar simplemente comentar que el remote_api no sólo permite acceder al datastore, aunque acceder a él sea quizá una de las mayores utilidades. Google explica por ejemplo también cómo crear una consola interactiva.

 

¡Votalo! 3 votos
¡Compártelo!

        

&nbps;

&nbps;

gimenete

Sobre gimenete

Gimenete es un tipo al que le encanta programar. Lleva media vida programando en Java, y ahora le da bastante también a Python. No le hace ascos a JavaScript. Su tema de investigación favorito ahora es el cloud computing.

 
Regístrate o haz login para participar.
¿Todavía no conoces debugmodeon?
debugmodeon es la red social para profesionales de la informática
descubre debugmodeon
 

5 comentarios en "Acceder al datastore de App Engine con remote_api"

tonny
tonny escribió
hace 1 años

#1   

Hola Gimenete ando dias con esto del remote api y no logro acceder
segui el tutorial de google http://code.google.com/intl/es-ES/appengine/docs/python/tools/uploadingdata.html
pero al hacer

appcfg.py upload_data --config_file=album_loader.py --filename=album_data.csv --kind=Album miapp

me sale el este error

Usage: appcfg.py [options] <action>

appcfg.py: error: no such option: --config_file

si hago esto, tambien hay error

tonny@debian-laptop:~/ciudadanos$ ../bin/google_appengine/appcfg.py upload_data 
Usage: appcfg.py [options] <action>

appcfg.py: error: Unknown action 'upload_data'

podrías talvez indicar como subir archivos csv al data store

Muchas gracias y felicitaciones por tus articulos.

Editado 1 veces. La última vez hace hace 1 años.

 

gimenete
gimenete escribió
hace 1 años

#2   

Pues no lo sé, porque yo sólo he usado la remote_api de forma programática. No he usado la opción "upload_data" nunca. He visto la documentación y aparentemente lo que intentas es correcto, así que más no puedo ayudarte :(

Editado 1 veces. La última vez hace hace 1 años.

 

tonny
tonny escribió
hace 1 años

#3   

Gracias con todo seguiré intentando...

 

Miuler
Miuler escribió
hace 1 meses

#4   

Hola Gimenete, me parece fantástico la manera en que han reducido los tiempos, de tardar 2 horas a solo 8min. eso si que es optimizar, bueno yo recién le estoy entrando con fuerza a esto del appengine de google, y me parece buena opción, aunque aún tengo mis dudas pero espero que poco a poco le tome más confianza a este sistema. Realmente gracias por este articulo, realmente fue muy interesante.

 

gimenete
gimenete escribió
hace 1 meses

#5   

Un placer, Miuler!

 
 
 
 

© Copyright 2008-2009 debug_mode=ON | Aviso legal | Contacto | FAQ | ¿Quiénes somos? |