Twisted Framework Learning

【Abstract】

Twisted is an asynchronous network framework. Unfortunately, most database api implementations only have blocking interfaces. Twisted.enterprise.adbapi is generated for this. It is a non-blocking interface of DB-API 2.0 API and can access various relational databases. .

Assuming you already know:

    Python :-)
    How to write a simple Twisted Server (see tutorial)
    Familiar with database related interfaces (see DBAPI 2.0)

[Quick overview]

Twisted is an asynchronous networking framework, which means that standard database modules cannot be used directly, as its interfaces are typically used like this:

[python]  view plain copy  
  1. # Create connection...  
  2. db = dbmodule.connect('mydb''andrew''password')  
  3. # ...which blocks for an unknown amount of time  
  4.   
  5. # create cursor  
  6. cursor = db.cursor()  
  7.   
  8. # Make a query...  
  9. resultset = cursor.query('SELECT * FROM table WHERE ...')  
  10. # ...for a longer period of time, even a few minutes  

These delays are unacceptable for an asynchronous framework. Therefore, Twisted provides twisted.enterprise.adbapi, an asynchronous wrapper that follows the DB-API 2.0 protocol.

adbapi performs blocking database operations in a separate thread, and calls back through this thread when the operation is completed. Colleagues, the original thread can continue its normal work and serve other requests.

[How to use adbapi?]

Instead of creating database connections directly, use the adbapi.ConnectionPool class to manage connections. This allows adbapi to use multiple connections, such as one connection per thread, which is very simple:

# Use the previous example "dbmodule" , to create a ConnectionPool object
from twisted.enterprise import adbapi
dbpool = adbapi.ConnectionPool("dbmodule", 'mydb', 'andrew', 'password')

Note:

    No need to import dbmodule directly. Just need Tell the adbapi.ConnectionPool constructor the name of the database module you are using such as MysqlDb.
    You need to pass the same parameters passed to dbmodule.connect() to the adbapi.ConnectionPool constructor.

Now we can make database queries:

[python]  view plain copy  
  1. # Equivalent to 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)  

Doing this is pretty straight forward, except for the return value of getAge, of course. It may return a Deferred object that will be called back when the database operation actually completes.
In addition to runQuery, there are runOperation and runInteraction, which will be called with a function. This function will be executed in the thread through adbapi.Transaction, essentially imitating the DB-API cursor. In any case, the database transaction will commit when the operation completes, unless an exception occurs that requires a rollback.

[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")  

By now, you know how to use a database in twisted. You may need to read the documentation of the adbapi module further to learn about other functions and methods, hopefully this article has pointed you to a bright path.

Reprinted to https://blog.csdn.net/vinrex/article/details/38423109

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325528749&siteId=291194637