twisted mysql_在Twisted下用MySQLadbapi获取自增id
D jango的ORM有一個很便捷的功能,其實也應該說是一個很基本的功能吧。就是在對一個model調(diào)用 save() 插入到數(shù)據(jù)庫后,會將創(chuàng)建的
D jango的ORM有一個很便捷的功能,其實也應該說是一個很基本的功能吧。就是在對一個model調(diào)用 save() 插入到數(shù)據(jù)庫后,會將創(chuàng)建的自增id同步到當前model上。SQL中調(diào)用 INSERT 默認的返回值是插入的行數(shù),就目前的應用來說,其實是一個沒啥意義的返回值,所以Django的ORM能夠處理好自增id的同步是一件很讓人愉悅的事。
不過沒有使用Django,最近用的是Twisted提供的adbapi,如何獲取自增id呢?
如果是我力挺的PostgreSQL的話,很簡單,,給 INSERT 加上 RETURNING 語句就可以了:
INSERT INTO distributors (did, dname)
VALUES (DEFAULT, 'XYZ Widgets') RETURNING did;
不過MySQL呢?
最近用了一陣子MySQL,只是從命令行自動補全這方面來說,就已經(jīng)明顯地感覺到和PostgreSQL的差距了。老實說真不知道為啥那么多人如此熱愛深愛著MySQL……
在StackOverflow上搜了一下,找到兩種方法,要么是使用
SELECT LAST_INSERT_ID();
或者是使用connector的 mysql_insert_id() 函數(shù),這個對于Python中的 MySQLdb 來說就是connection的 insert_id() 函數(shù),比如:
conn = MySQLdb.connect(host='heaven', user='god',
passwd='jesus', db='elysium')
cursor = conn.cursor()
cursor.execute('INSERT INTO account VALUES (%s, %s)',
('satan', 'male or female, who knows'))
new_id = conn.insert_id() # <= 就是這玩意兒
過程也還算簡單,但是對于Twisted的adbapi來說,我們的活并沒有結(jié)束。為啥呢?因為adbapi用的是線程池來管理MySQL的連接的,每次Query調(diào)用,都會從線程池中獲取一個線程,然后將相應的事務(wù)defer到該線程來處理。其默認的事務(wù)是以單個SQL語句為劃分的,所以說,對于MySQL這樣在執(zhí)行完后還需要做其他操作的需求來說,默認的接口是無法滿足的。這兒我再吐一下槽,還是pg好啊……
默認接口不夠用,那我們就只能擴展它了。稍稍看一下adbapi的源代碼我們可以發(fā)現(xiàn),對于通常事務(wù),adbapi其實是使用了 runInteraction 這個接口函數(shù)的。具體不同的事務(wù),adbapi是將相應的callback作為其第一個參數(shù),然后在 deferToThreadPool 時指定線程運行該callback來實現(xiàn)。所以,我們只需要為MySQL定義一種新的事務(wù)就可以了。
下面就是我們需要定義的新事務(wù):
def runMySQLInsert(self, *args, **kw):
assert self.dbapiName == 'MySQLdb'
return self.runInteraction(self._runMySQLInsert, *args, **kw)
def _runMySQLInsert(self, trans, *args, **kw):
trans.execute(*args, **kw)
return trans.connection.insert_id()
Ok,接下來,把這兩個函數(shù)Monkey Patch到adbapi上就完事了:)
本條技術(shù)文章來源于互聯(lián)網(wǎng),如果無意侵犯您的權(quán)益請點擊此處反饋版權(quán)投訴
本文系統(tǒng)來源:php中文網(wǎng)
總結(jié)
以上是生活随笔為你收集整理的twisted mysql_在Twisted下用MySQLadbapi获取自增id的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jenkins linux编译c,【Li
- 下一篇: oracle立即关闭数据库,Oracle