標籤:variables ext ase not ctc factory 欄位 rate 情境
psycopg2 點擊可查看文檔
在使用ORM之前,一直在用psycopg2去操作資料庫。原因在於比較喜歡寫原生的sql語句,雖然開發速度比使用ORM慢,但是自我感覺可靠,而且在一些複雜sql時候更方便(不用處理裡面的關係映射,這非常不好理解, 也可能是自己太笨了-_-)。然而也遇到一些問題,使用fetchall()方法或者fetchone()方法擷取的資料的到的結果往往是一個元組。只能通過索引擷取相應的資料,相比字典可操作行相對較低,因為不知道什麼時候擷取欄位就可能增加,而擷取索引就會相應的改變。
我之前的處理方法是這樣的
data = [dict((cursor.description[i][0], value) for i, value in enumerate(row)) for row in cursor.fetchall()]
在仔細查看文檔發現,其實psycopg2已經有這樣的處理了, 只需要使用cursor_factory=psycopg2.extras.RealDictCursor參數就可以了
貼上代碼,歡迎批評指正~
# -*-coding: utf-8 -*-from flask import current_appimport psycopg2import psycopg2.extrasclass DbModel(object): def __init__(self, autocommit=True): self.conn = psycopg2.connect(host=current_app.config[‘HOST‘], port=current_app.config[‘PORT‘], user=current_app.config[‘USER‘], password=current_app.config[‘PASSWORD‘], database=current_app.config[‘DATABASE‘]) #是否執行後立即提交,預設為True;如果應用情境中需要使用事務,設定為False。在最後執行commit()方法或者rollback()方法 self.autocommit = autocommit self.cur = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) def getOne(self, sql=‘‘,data=()): self.cur.execute(sql, data) self.data = self.cur.fetchone() return self.data def getAll(self, sql=‘‘, data=()): self.cur.execute(sql, data) self.data = self.cur.fetchall() return self.data def writeDb(self, sql=‘‘, data=()): self.cur.execute(sql, data) self.data = self.cur.rowcount if self.autocommit: self.commit() return self.data def writeGetId(self, sql=‘‘, data=()): self.cur.execute(sql, data) self.data = self.cur.fetchone() if self.autocommit: self.commit() return self.data def getSql(self, sql="", data=()): return self.cur.mogrify(sql, data) def commit(self): self.conn.commit() self.closeall() def closeall(self): self.cur.close() self.conn.close()
附上基本的使用方法
import DbModel sql = ‘SELECT * FROM company WHERE mobileno=%s;‘ parms = (‘18611111111‘,) #如果參數是只有一個元素的元組,逗號必須;字典方式傳遞參數,請看文檔 data = DbModel().getAll(sql, parms) print data #postgres returning id 可以返回剛剛執行語句的id sql = "UPDATE company SET name=%s WHERE mobileno=%s RETURNING id;" parms = (‘測試一下‘, ‘18611111111‘) data = DbModel().writeGetId(sql, parms) print data
一些其他的使用方法。偶爾會用到的
1,sql語句中in的使用
ids = [10, 20, 30]cur.execute("SELECT * FROM data WHERE id = ANY(%s);", (ids,))
2,重要提示,防止sql注入
Warning Never, never, NEVER use Python string concatenation (+) or string parameters interpolation (%) to pass variables to a SQL query string. Not even at gunpoint.
就是說,永遠不要用python字串的加號把語句和參數連起來去執行
python使用psycopg2