Twisted 框架学习

【摘要】

Twisted 是一个异步网络框架,不幸的是大部分数据库api实现只有阻塞式接口,twisted.enterprise.adbapi为此产生,它是DB-API 2.0 API的非阻塞接口,可以访问各种关系数据库。

假定你已经了解:

    Python :-)
    如何写一个简单的 Twisted Server (参见 tutorial)
    熟悉数据库的相关接口 (参考 DBAPI 2.0)

【快速概览】

Twisted 是一个异步网络框架, 意味着标准数据库模块无法直接使用, 因为一般会这样来使用其接口:

[python]  view plain  copy
  1. # 创建连接...  
  2. db = dbmodule.connect('mydb''andrew''password')  
  3. # ...which blocks for an unknown amount of time  
  4.   
  5. # 创建游标  
  6. cursor = db.cursor()  
  7.   
  8. # 进行查询...  
  9. resultset = cursor.query('SELECT * FROM table WHERE ...')  
  10. # ...持续一段较长的时间,乃至数分钟  

对于异步框架而言,这些延迟是无法接受的。因此, Twisted 提供了 twisted.enterprise.adbapi, 遵循DB-API 2.0协议的一个异步封装。

adbapi 在单独的线程里面进行阻塞数据库操作, 当操作完成的时候仍然通过这个线程来进行回调。同事,原始线程能继续进行正常的工作,服务其他请求。

【如何使用 adbapi?】

不同于直接创建数据库连接, 而是使用 adbapi.ConnectionPool 类来管理连接. 这就可以让 adbapi 来使用多个连接, 比如每个线程一个连接,这很简单:

# 使用前面例子的 "dbmodule" , 来创建一个 ConnectionPool 对象
from twisted.enterprise import adbapi
dbpool = adbapi.ConnectionPool("dbmodule", 'mydb', 'andrew', 'password')

需要注意的事项:

    无需直接导入 dbmodule. 只需要告诉 adbapi.ConnectionPool 构造器你用的数据库模块的名称比如 MysqlDb.
    你需要把传入 dbmodule.connect() 的参数同样的传给adbapi.ConnectionPool构造器。

现在我们可以进行数据库查询:

[python]  view plain  copy
  1. # 等价于 cursor.execute(statement), return cursor.fetchall():  
  2. def getAge(user):  
  3.     return dbpool.runQuery("SELECT age FROM users WHERE name = ?", user)  
  4.   
  5. def printResult(l):  
  6.     if l:  
  7.         print l[0][0], "years old"  
  8.     else:  
  9.         print "No such user"  
  10.   
  11. getAge("joe").addCallback(printResult)  

这样做非常直接, 当然除了 getAge 的返回值. 它可能会返回一个Deferred延迟对象,它会在数据库操作真正完成的时候进行回调。
除了 runQuery, 还有 runOperation 和 runInteraction,调用它们的时候会带上一个function。这个function会在线程中通过 adbapi.Transaction 来执行, 本质上是模仿 DB-API cursor。在任何情况下,数据库事务将在操作完成时进行提交,除非发生异常需要回滚。

[python]  view plain  copy
  1. def _getAge(txn, user):  
  2.     # this will run in a thread, we can use blocking calls  
  3.     txn.execute("SELECT * FROM foo")  
  4.     # ... other cursor commands called on txn ...  
  5.     txn.execute("SELECT age FROM users WHERE name = ?", user)  
  6.     result = txn.fetchall()  
  7.     if result:  
  8.         return result[0][0]  
  9.     else:  
  10.         return None  
  11.   
  12. def getAge(user):  
  13.     return dbpool.runInteraction(_getAge, user)  
  14.   
  15. def printResult(age):  
  16.     if age != None:  
  17.         print age, "years old"  
  18.     else:  
  19.         print "No such user"  
  20.   
  21. getAge("joe").addCallback(printResult)  

另外值得一提的是假定这些例子中 dbmodule 使用了 ”qmarks“ 式参数 (见 DB-API 规范). 如果你的 dbmodule 使用了一种不同的参数模式 (e.g. pyformat),那么使用即可。Twisted 并没有提供所有类型的魔法参数 - runQuery (query, params, ...)  会直接映射到 cursor.execute(query, params, ...).

下面是各个数据库适配的例子:
注意到第一个参数就是数据库的模块名称,通常的你会 import 然后 connect(...), 剩下的参数也是 connect(...) 方法所必须的。

[python]  view plain  copy
  1. from twisted.enterprise import adbapi  
  2.   
  3. # Gadfly  
  4. cp = adbapi.ConnectionPool("gadfly""test""/tmp/gadflyDB")  
  5.   
  6. # PostgreSQL PyPgSQL  
  7. cp = adbapi.ConnectionPool("pyPgSQL.PgSQL", database="test")  
  8.   
  9. # MySQL  
  10. cp = adbapi.ConnectionPool("MySQLdb", db="test")  

现在为止,您已经知道如何在twisted中使用数据库了。你也许需要进一步阅读 adbapi 模块的 文档以了解其它的功能和方法, 希望这篇文章给你指明了一条光明之路。

转载至https://blog.csdn.net/vinrex/article/details/38423109

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值