使用Python Twistar保存/插入多个记录

时间:2015-04-09 22:02:22

标签: python asynchronous twisted

扩展Twistar example code,我正在尝试一次写多条记录:

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

所以这显然不对,但无论如何这两个记录都被添加到数据库中。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

首先,您需要像这样返回u.save()的延迟:

 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) 

这样,只有在保存最后一个用户时才能关闭反应堆。