Inicio > Programación FAQ , Desarrollo de Software > Migración Blobstore GAE a una aplicación Desarrollo de Recursos Humanos

Migración Blobstore GAE a una aplicación DRH

Google App Engine Si usted está planeando migrar la aplicación de Google App Engine para el "nuevo" esquema de base de datos de alta replicación, entonces usted probablemente sabe que el proceso de migración de Google no manejar archivos Blobstore.

Aquí encontrará algunos scripts de Python que le ayudarán a mover los archivos Blobstore de la aplicación antigua a la nueva, y corregir todas las referencias en la base de datos nueva. Como siempre, utilice a su propio riesgo, no trates de hacer nada sin la lectura y la comprensión de las secuencias de comandos, de lo contrario puede perder sus datos de forma permanente.

Algunas consideraciones:

  • Hicimos utilizar estos scripts en nuestra aplicación propia, así que puedo decir que funciona. Sin embargo, tuve que editar los guiones originales para hacerlos más "genérico", retire mis referencias de bases de datos y los nombres, etc,
  • Voy a tratar de describir las fases de la migración, pero por favor no trates de hacer nada antes de leer el artículo completo en primer lugar.
  • Esto no es por cualquier otro medio destinado a ser una migración totalmente automático, de hecho, los pasos necesita ser ejecutado manualmente una por una.
  • Los scripts no se migran los archivos grandes. Hemos migrado archivos de hasta 40Mb sin problemas, pero si usted tiene archivos más grandes que eso, probablemente, se producirá un error. Por ejemplo, hemos tratado de un archivo de 300Mb, sin éxito, la razón es que el archivo debe ser descargado desde la aplicación antigua a la nueva, y hay un tiempo de espera de 1 minuto para que las solicitudes de aplicaciones, así que si la descarga tarda más de que va a fallar .
¿Cómo funciona el script

Usted tendrá que poner el guión en sus aplicaciones, tanto el nuevo (HRD) y el viejo. Básicamente, expone cuatro direcciones URL y tendrá que acceder a dos de ellos de la aplicación de los recursos humanos.
De esta manera vas a descargar todos los archivos BLOB de la aplicación antigua a la nueva, el script creará un modelo que mantiene un mapa entre las referencias antiguas y nuevas.
El último paso es migrar las referencias antiguas a la nueva en las bases de datos de recursos humanos.

Requisitos previos
  • Todas las referencias a archivos BLOB en sus modelos deben ser del tipo blobstore.BlobReferenceProperty , si no que tendrá que ajustar en primer lugar.
  • Migración de las bases de datos desde la aplicación antigua a la nueva aplicación de los recursos humanos mediante el método estándar de Google la migración .
Pasos
  • Agregar el URL para su aplicación
def main():
    application = webapp.WSGIApplication(
          [
           # ... Your app URLs here ...
           # TODO - REMOVE THIS AFTER MIGRATION
           ('/mig/__getblob/(.+)', GetBlob),
           ('/mig/__getblobkeys/?', GetBlobKeys),
           ('/mig/__migrateblobs/?', MigrateBlobs),
           ('/mig/__migratereferences/?', MigrateBlobReferences),
          ], debug=True)
    run_wsgi_app(application)

if __name__ == '__main__':
  main()
  • A continuación, agregue el código de la migración
####
# TEMPORARY BLOBSTORE MIGRATION CODE
####

MODELS = (
    # add your (model, blobinfo_field_name) tuples here
    ("myModel1", "blobinfofield"),
    ("myModel2", "BlobInfo"),
)

class mig_BlobMig(db.Model):
    fname = db.StringProperty()
    blobinfo = blobstore.BlobReferenceProperty()
    origkey = db.StringProperty()

class MigrateBlobReferences(blobstore_handlers.BlobstoreDownloadHandler):
    '''Migrate blob info references'''
    def get(self):
        import models
        tb = dict([(str(blob.origkey), blob.blobinfo) for blob in mig_BlobMig.all()])
        for modelname, field in MODELS:
            to_put = []
            skipped = 0
            for obj in db.GqlQuery('SELECT * FROM %s'%modelname):
                oldkey = getattr(obj, field)
                if oldkey:
                    oldkey = str(oldkey.key())
                if oldkey in tb:
                    setattr(obj, field, tb[oldkey])
                    to_put.append(obj)
                else:
                    skipped += 1
            db.put(to_put)
            self.response.out.write("[%s] - Migrated %d references!<br/>Skipped: %d<br/>\n"%(modelname, len(to_put), skipped))

class MigrateBlobs(blobstore_handlers.BlobstoreDownloadHandler):
    '''Migrate blobs from myoldapp to mynewapp'''
    def get(self):
        import time
        from google.appengine.api import files, urlfetch
        start_time = time.time()
        timed_out = False
        migrated_keys = set([str(blob.origkey) for blob in mig_BlobMig.all()])
        all_blobs = eval(urlfetch.fetch("https://myoldapp.appspot.com/mig/__getblobkeys", deadline=15.0).content)
        all_keys = set(all_blobs.keys())
        missing_keys = list(all_keys-migrated_keys)
        if not missing_keys:
            self.response.out.write("Nothing to migrate!")
            return
        # Download 20 blobs per round
        download_keys = missing_keys[:20]
        MAXSIZE = (10*1024*1024) # 10MB
        for origkey in download_keys:
            blob = all_blobs[origkey]
            url = "https://myoldapp.appspot.com/mig/__getblob/%s"%urllib.quote_plus(origkey)
            blob_path = files.blobstore.create(mime_type=blob["content_type"], _blobinfo_uploaded_filename=blob["filename"])
            fsize = int(blob["size"])
            with files.open(blob_path, 'a') as f:
                for first_byte in range(0, fsize, MAXSIZE):
                    last_byte = (first_byte+MAXSIZE-1)
                    if last_byte>=fsize: last_byte=(fsize-1)
                    bytes_range = "bytes=%d-%d"%(first_byte,last_byte)
                    logging.info("Downloading [%s] range [%s] key=[%s]"%(blob["filename"], bytes_range, origkey))
                    res = urlfetch.fetch(url, deadline=35.0, headers={"Range": bytes_range})
                    f.write(res.content)
                    del res.content
                    del res
                    if (time.time()-start_time > 40.0):
                        timed_out = True
                        break
            if timed_out:
                self.response.out.write("Stopped due to time limit!<br/>")
                break
            files.finalize(blob_path)
            blob_key = files.blobstore.get_blob_key(blob_path)
            blob_info = blobstore.BlobInfo.get(blob_key)
            mig_BlobMig(fname=blob["filename"], blobinfo=blob_info, origkey=origkey).put()
            logging.info("Successfully downloaded [%s]!!!"%(blob["filename"]))
            self.response.out.write("Migrated %s<br/>"%blob["filename"])
        self.response.out.write("<br/>SUCCESS!")

class GetBlobKeys(blobstore_handlers.BlobstoreDownloadHandler):
    '''Retrieve all Blob Keys, as a JSON string'''
    def get(self):
        from simplejson.encoder import JSONEncoder
        blobs = {}
        for blob_info in blobstore.BlobInfo.all():
            blobs[str(blob_info.key())] = {
             "filename":str(blob_info.filename),
             "content_type":str(blob_info.content_type),
             "size":int(blob_info.size),
             "key":str(blob_info.key()),
            }
        self.response.headers["Content-type"] = "application/json"
        self.response.out.write(JSONEncoder().encode(blobs))

class GetBlob(blobstore_handlers.BlobstoreDownloadHandler):
    '''Download a blob given its key'''
    def get(self, blobkey):
        blobkey = str(urllib.unquote(blobkey))
        blob_info = blobstore.BlobInfo.get(blobkey)
        if not blob_info:
            self.error(404)
            return
        self.response.headers["Content-type"] = str(blob_info.content_type)
        self.send_blob(blob_info, save_as=True)

####
# END OF TEMPORARY BLOBSTORE MIGRATION CODE
####
  • Modificar el MODELS variable de la adición de los modelos y campos blob información que usted necesita para actualizar
  • Vuelva a colocar myoldapp URL con la dirección URL real de su aplicación anterior
  • Sincronizar el código de ambas aplicaciones
  • Abra el navegador y el punto a http://mynewapp.appspot.com/mig/__migrateblobs . Por supuesto, mynewapp debe ser reemplazado con el nombre real de aplicación de los recursos humanos. Esto descargará las manchas de la aplicación antigua a la nueva. Debido a que existe una limitación de tiempo de espera que tendrá que llamar muchas veces. ADVERTENCIA: Usted debe hacer una sola solicitud en el momento, nunca se llame a partir de dos navegadores, separadores, al mismo tiempo o si se hace un lío la base de datos de migración!. Así que este paso debe ser cuidadosamente ejecutada, una solicitud en tiempo y esperar a que termine antes de llamar a la siguiente. Repita este procedimiento hasta que aparezca el mensaje Nothing to migrate! . Este paso puede ser muy lento dependiendo de la cantidad de archivos que tiene en el blobstore y el tamaño de ellos, puede ser que tome mucho tiempo para obtener todos los archivos descargados. ¡Tenga paciencia!
  • Una vez que todos los archivos se copian en la nueva aplicación, apuntar el navegador para http://mynewapp.appspot.com/mig/__migratereferences . En caso de ser rápido, y necesita que se ejecute sólo una vez. Sin embargo, no pasa nada si lo llamo más de una vez.
  • El último paso, eliminar el código de la migración y las direcciones URL y sincronizar el código de nuevo. También puede quitar el mig_BlobMig base de datos.

Migración Buena.

  1. No hay comentarios todavía.

Protección anti-spam por WP Captcha-Free