Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python GAE数据存储上的模式迁移_Python_Google App Engine_Migration_Schema_Google Cloud Datastore - Fatal编程技术网

Python GAE数据存储上的模式迁移

Python GAE数据存储上的模式迁移,python,google-app-engine,migration,schema,google-cloud-datastore,Python,Google App Engine,Migration,Schema,Google Cloud Datastore,首先,这是我关于堆栈溢出的第一篇文章,所以请原谅任何新手的错误步骤。如果我能更清楚地说明我的问题框架,请让我知道 我在Google App Engine上运行一个大型应用程序,并且一直在添加新功能,这些功能迫使我修改旧的数据类并添加新的数据类。为了清理数据库并更新旧条目,我一直在尝试编写一个脚本,该脚本可以迭代类的实例,进行更改,然后重新保存它们。问题是,当你呼叫服务器的时间超过几秒钟时,谷歌应用引擎就会超时 我已经为这个问题挣扎了好几个星期了。我找到的最佳解决方案是: 我为自己的网站创建了该代

首先,这是我关于堆栈溢出的第一篇文章,所以请原谅任何新手的错误步骤。如果我能更清楚地说明我的问题框架,请让我知道

我在Google App Engine上运行一个大型应用程序,并且一直在添加新功能,这些功能迫使我修改旧的数据类并添加新的数据类。为了清理数据库并更新旧条目,我一直在尝试编写一个脚本,该脚本可以迭代类的实例,进行更改,然后重新保存它们。问题是,当你呼叫服务器的时间超过几秒钟时,谷歌应用引擎就会超时

我已经为这个问题挣扎了好几个星期了。我找到的最佳解决方案是:

我为自己的网站创建了该代码的一个版本,您可以在这里看到:

def schema_migration (self, target, batch_size=1000):
    last_key = None
    calls = {"Affiliate": Affiliate, "IPN": IPN, "Mail": Mail, "Payment": Payment, "Promotion": Promotion}

    while True:
        q = calls[target].all()
        if last_key:
            q.filter('__key__ >', last_key)
        q.order('__key__')
        this_batch_size = batch_size

        while True:
            try:
                batch = q.fetch(this_batch_size)
                break
            except (db.Timeout, DeadlineExceededError):
                logging.warn("Query timed out, retrying")
                if this_batch_size == 1:
                    logging.critical("Unable to update entities, aborting")
                    return
                this_batch_size //= 2

        if not batch:
            break

        keys = None
        while not keys:
            try:
                keys = db.put(batch)
            except db.Timeout:
                logging.warn("Put timed out, retrying")

        last_key = keys[-1]
        print "Updated %d records" % (len(keys),)
奇怪的是,该代码对于具有100-1000个实例的类非常有效,而且脚本通常需要10秒左右的时间。但是,当我尝试为数据库中的类运行代码时,该脚本会运行30秒,然后我收到以下消息:

“错误:服务器错误

服务器遇到错误,无法完成您的请求。 如果问题仍然存在,请报告您的问题,并说明此错误消息和导致此问题的查询。“”

知道为什么GAE在30秒后超时吗?我能做些什么来解决这个问题

谢谢你!
Keller

您听到的声音是第二个DeadLineExceedError。AppEngine请求每次只能运行30秒。当DeadLineExceedError出现时,您的工作是停止处理并在时间不足时进行整理,下次出现时,您将无法捕获它


您应该考虑使用将迁移拆分为批,并使用任务队列运行每个批。

解决方案的开始是迁移到使用GAE的任务队列。此功能将允许您将稍后发生的更多工作排队

这实际上并不能立即解决问题,因为即使是任务队列也仅限于较短的时间片。但是,您可以展开循环,一次处理数据库中的大量行。完成每个批处理后,它可以检查运行了多长时间,如果足够长,它可以在队列中启动新任务eue继续当前任务将停止的位置


另一种解决方案是不迁移数据。更改实现逻辑,以便每个实体都知道数据是否已迁移。新创建的实体或更新的旧实体将采用新格式。由于GAE不要求实体具有所有相同的字段,因此您可以轻松地在关系数据库上执行此操作tabase,那不太实际。

任务队列现在可以运行10分钟。因为它们可以在10秒内完成1000次迁移,所以它们可能能够在10分钟内完成整个迁移。感谢Ozone和MacGuy的帮助!我非常感谢您抽出时间指导我正确的方向。正确使用任务队列API n哦……你真的应该早点问这个问题。要么在这里,要么在应用引擎Google Group()上。迁移是一个常见的问题,人们会有很多解决方案。不要孤军奋战。