扩展Twistar示例代码,我试图同时写入多条记录:
from twisted.enterprise import adbapi
from twistar.registry import Registry
from twistar.dbobject import DBObject
from twisted.internet import reactor
class User(DBObject):
pass
def done(user):
print "A user was just created with the name %s" % user.first_name
#The example calls reactor.stop() here
Registry.DBPOOL = adbapi.ConnectionPool('MySQLdb', user="twistar", passwd="apass", db="twistar")
# I've added this function:
def write_user(first_name)
u = User(first_name=first_name)
u.save().addCallback(done)
new_users = ["Alice","Bob"]
for new_user in new_users:
#Here's where I call the function repeatedly:
write_user(new_user)
reactor.run()
实际上,此示例打印:
A user was just created with the name Alice
A user was just created with the name Bob
但是程序永远不会退出!将reactor.stop()
添加到done()
函数会导致脚本在仅打印后退出
A user was just created with the name Alice
所以这显然是不对的,但无论如何,这两条记录都被添加到了数据库中。
我该怎么做?
首先,您需要返回u.save()
的defer,如下所示:
def write_user(first_name)
u = User(first_name=first_name)
return u.save()
然后,在您的循环中,当您write_user
时,您需要存储那些Deferred:
results = []
for new_user in new_users:
results.append(write_user(new_user))
# Here, all deferred except the last one will call done.
DeferredList(results[:-1]).addCallback(done)
# Here, the last Deferred will call reactor.stop after he's done.
results[-1].addCallback(done).addCallback(reactor.stop)
这样,只有在保存了最后一个用户后,才能关闭反应器。