是否可以从Google App Engine一起获取许多对象?

时间:2015-02-19 15:09:00

标签: python google-app-engine csv

我们在Google App Engine中有大约5,000个类Domain对象,我们希望将域列表导出为CSV。每个域都链接到DomainStateData类的对象:

class DomainStateData(db.Expando, ExpandoEntity):
    plan = db.ReferenceProperty(Plan)
    plan_expiration = db.DateTimeProperty()
    trial_expiration = db.DateTimeProperty()

    date_created = db.DateTimeProperty(auto_now_add=True, indexed=True)
    last_modified = db.DateTimeProperty(auto_now=True)


class Domain(db.Expando, ExpandoEntity, SocialIconsEntity):
    """
    Domain Model
    """
    domain = db.StringProperty(required=True)
    ...
    _state_data = db.ReferenceProperty(DomainStateData)

    @property
    def state_data(self):
        try:
            if not self._state_data:
                # try to get it, if not, build it
                sd = DomainStateData.get_by_key_name(self.key().name())
                if not sd:
                    sd = DomainStateData(key_name=self.key().name()).put()
                self._state_data = sd
                self.put()
                return self._state_data
            else:
                return self._state_data
        except ReferencePropertyResolveError:
            self._state_data = DomainStateData(key_name=self.key().name()).put()
            self.put()
            return self._state_data

我写了一个代码,它将100个域导出为CSV(需要5秒),但如果我尝试获取所有5,000个域,我会得到超时,即60秒。是否可以在没有超时的情况下一起获取所有DomainStateData对象?这是我将域导出为CSV的代码:

import sys
sys.path.insert(0, 'libs')

import webapp2
import datetime
import csv
from models import Domain


class ExportAllDomainsToCsvHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/csv'
        self.response.headers['Content-Disposition'] = 'attachment; filename="All Domains [{0}].csv"'.format(str(datetime.date.today()))
        writer = csv.writer(self.response.out)
        writer.writerow(["Domain", "Current state", "Plan expiration date", "Trial expiration date", "Current oauth user"])
        all_domains = Domain.all().fetch(100)
        all_domains.sort(key=lambda domain: (0 if domain.state_data.plan_expiration is None else 1, domain.state_data.plan_expiration, 0 if domain.state_data.trial_expiration is None else 1, domain.state_data.trial_expiration, domain.domain))
        for domain in all_domains:
            if (domain.state_data.plan_expiration is None):
                domain_plan_expiration = "No plan expiration date"
            else:
                domain_plan_expiration = domain.state_data.plan_expiration.strftime('%Y-%m-%d')
            if (domain.state_data.trial_expiration is None):
                domain_trial_expiration = "No trial expiration date"
            else:
                domain_trial_expiration = domain.state_data.trial_expiration.strftime('%Y-%m-%d')
            writer.writerow([domain.domain, domain.cur_state.name, domain_plan_expiration, domain_trial_expiration, domain.admin])


app = webapp2.WSGIApplication([
    ("/csv/export_all_domains_to_csv", ExportAllDomainsToCsvHandler)
], debug=True)

1 个答案:

答案 0 :(得分:0)

好的,我找到了解决方案。我直接从数据库中获取了所有DomainStateData对象,现在需要35秒才能创建包含所有域的CSV。这是我的代码,我没有更改模型:

import sys
sys.path.insert(0, 'libs')

import webapp2
import datetime
import csv
from models import DomainStateData, Domain


class ExportAllDomainsToCsvHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/csv'
        self.response.headers['Content-Disposition'] = 'attachment; filename="All Domains [{0}].csv"'.format(str(datetime.date.today()))
        writer = csv.writer(self.response.out)
        writer.writerow(["Domain", "Current state", "Plan expiration date", "Trial expiration date", "Current oauth user"])
        all_domain_state_data_dict = dict()
        all_domain_state_data = DomainStateData.all().fetch(1000000)
        all_domains = Domain.all().fetch(1000000)
        for domain_state_data in all_domain_state_data:
            all_domain_state_data_dict[domain_state_data.key().name()] = domain_state_data
        for domain in all_domains:
            if (domain.key().name() in all_domain_state_data_dict):
                domain.__state_data = all_domain_state_data_dict[domain.key().name()]
        all_domains.sort(key=lambda domain: (0 if domain.__state_data.plan_expiration is None else 1, domain.__state_data.plan_expiration, 0 if domain.__state_data.trial_expiration is None else 1, domain.__state_data.trial_expiration, domain.domain))
        for domain in all_domains:
            if (domain.__state_data.plan_expiration is None):
                domain_plan_expiration = "No plan expiration date"
            else:
                domain_plan_expiration = domain.__state_data.plan_expiration.strftime('%Y-%m-%d')
            if (domain.__state_data.trial_expiration is None):
                domain_trial_expiration = "No trial expiration date"
            else:
                domain_trial_expiration = domain.__state_data.trial_expiration.strftime('%Y-%m-%d')
            writer.writerow([domain.domain, domain.cur_state.name, domain_plan_expiration, domain_trial_expiration, domain.admin])

app = webapp2.WSGIApplication([
    ("/csv/export_all_domains_to_csv", ExportAllDomainsToCsvHandler)
], debug=True)