如何在调用db.put()之前在GAE Python中查找db.Model实例的大小?

时间:2011-02-27 13:28:07

标签: python google-app-engine google-cloud-datastore

我正在为我的应用程序编写优化器,因此db.put()尽可能少地调用。我坚持以下问题:

我有许多从db.Model派生的类。存储在列表中的那些类的实例:

class DBPutter:
    data = [] # list of instances
    def add(self, model):
        # HERE I WANT TO CHECK THAT self.data IS NOT EXEEDING 1MB
        self.data.append(model)
        if len(self.data) == 1000:
            self.flush()  # actual call to db.put() using deferred

通过这种方法,我收到了很多RequestTooLargeError个例外。如何检查我的数据是否没有超过1MB?

3 个答案:

答案 0 :(得分:4)

Pympler有一个asizeof方法,应该在python 2.5中运行:http://code.google.com/p/pympler/

我认为你过度优化了。如果在推杆中有1000个对象之前关闭实例,则可能会丢失数据。此外,我认为使用带有大量数据的延迟库将导致至少两个db.puts。提交任务时(因为有效负载超过10k),并且任务内部有一个,实际上是在编写模型。

答案 1 :(得分:3)

根据1.4.0发行说明:

  • 已删除数据存储批量获取/放置/删除操作的大小和数量限制。单个实体仍然限制为1 MB,但您的应用程序可能会将获取/放入/删除调用一起批处理多个实体,因为整个数据存储截止日期将允许。

也就是说,使用deferred是没有意义的:任务队列有效负载限制为10k,如果延迟的有效负载大于此值,它将创建一个数据存储实体来存储有效负载。结果,它正在执行无论如何,数据存储操作,所以你也可以自己动手。

但是,如果您要存储数千个实体,那么您几乎肯定希望首先在任务队列中执行整个过程,而不是在交互式请求中。

答案 2 :(得分:1)

我不使用GAE,但您可以尝试在每个模型上调用sys.getsizeof并验证总和小于1 MB。

编辑:请参阅此ActiveState recipe以获取sys.getsizeof的替代方法,该方法应在Python 2.5中有效。