我想为GAE的Mapreduce框架编写一个自定义的OutputWriter。这个OutputWriter应该打开到一个开放的MongoDB端口的直接tcp连接,并将reduce步骤的结果直接写入这个数据库。在
我使用pymongo与mongodb交互。现有的Mapreduce库要求输出编写器是JSON可序列化的。一旦输出编写器与mongodb实例建立了连接,如下所示:
from pymongo import Connection
conn = Connection(host=MONGODB_HOST, port=MONGODB_PORT)
db = conn.test_db
db.authenticate(MONGODB_USERNAME, MONGODB_PASSWD)
我想序列化Connection
(类型为pymongo.connection.Connection
)或{pymongo.database.Database
)。当然,这些对象不是JSON可序列化的,所以我想我可以用一个pickled数据库制作一个JSON dict,但是pymongo似乎并不支持pickle这些对象,也就是说,它们都没有__getstate__
方法。在
我假设我可以简单地存储连接和身份验证参数,并在OutputWriter反序列化时重新打开一个连接,但这似乎过于繁琐,而且耗费时间和资源。在
有人能给我指出一个变通办法,或者也许是一种我没有想到的不同的序列化?在
你还希望能做什么?一般来说,数据库连接是围绕Python外部的一些对象(套接字、文件句柄、C库创建的不透明对象的实例等)的包装器,所以不能只存储一个并在进程的稍后实例中恢复它,将其传递给另一个进程,等等,像这样的类的任何通用序列化都会通过存储连接参数和重新连接来工作。在
但在很多情况下你不想这么做。(另外,请记住,使某个对象可pickle也使其可复制,而且还远不清楚您是否总是希望通过打开一个新的不同但等效的连接来复制数据库连接。)这就是为什么大多数数据库连接对象和类似的东西都不可pickle的原因。在
同时,如果您试图在一个进程中传递这些,而连接仍然是活动的…那么您首先不应该对它们进行酸洗,只需传递对周围连接的引用。在
所以不管怎样,我建议你按照你建议但又不想做的去做,而是通过子类化(或monkeypatching)这两个类来结束它,这样就可以直接对它们进行pickle,而不是传递一堆单独的参数,让其他人都知道如何处理它。在
我认为
__getstate__
在这里不起作用。这意味着您可以在默认情况下建立数据库连接,然后构造实例,然后设置属性或调用方法,但大多数数据库连接类都要求您将参数传递到构造函数调用中,以便在__new__
或__init__
时间使用。但是,您可能只需要__getnewargs__
(这实际上比__getstate__
更简单)就可以做到这一点。如果没有,则需要更复杂的__reduce__
机制。在相关问题 更多 >
编程相关推荐