幾個複雜的ORM方式都已介紹完了,剩下一些常用的刪除、獲取記錄數量、統計合計數、獲取最大值、獲取最小值等方法我就不一一詳細介紹了,直接給出代碼大家自行查看。 1 #!/usr/bin/env python 2 # coding=utf-8 3 4 from common import db_help ...
幾個複雜的ORM方式都已介紹完了,剩下一些常用的刪除、獲取記錄數量、統計合計數、獲取最大值、獲取最小值等方法我就不一一詳細介紹了,直接給出代碼大家自行查看。
1 #!/usr/bin/env python 2 # coding=utf-8 3 4 from common import db_helper 5 6 7 class LogicBase(): 8 """邏輯層基礎類""" 9 10 def __init__(self, db, is_output_sql, table_name, column_name_list='*', pk_name='id'): 11 """類初始化""" 12 # 資料庫參數 13 self.__db = db 14 # 是否輸出執行的Sql語句到日誌中 15 self.__is_output_sql = is_output_sql 16 # 表名稱 17 self.__table_name = str(table_name).lower() 18 # 查詢的列欄位名稱,*表示查詢全部欄位,多於1個欄位時用逗號進行分隔,除了欄位名外,也可以是表達式 19 self.__column_name_list = str(column_name_list).lower() 20 # 主健名稱 21 self.__pk_name = str(pk_name).lower() 22 23 ##################################################################### 24 ### 執行Sql ### 25 26 def select(self, sql): 27 """執行sql查詢語句(select)""" 28 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db: 29 # 執行sql語句 30 result = db.execute(sql) 31 if not result: 32 result = [] 33 return result 34 35 def execute(self, sql): 36 """執行sql語句,並提交事務""" 37 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db: 38 # 執行sql語句 39 result = db.execute(sql) 40 if result: 41 db.commit() 42 else: 43 result = [] 44 return result 45 46 def copy(self, values, columns): 47 """批量更新數據""" 48 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db: 49 # 執行sql語句 50 result = db.copy(values, self.__table_name, columns) 51 return result 52 53 def get_model(self, wheres): 54 """通過條件獲取一條記錄""" 55 # 如果有條件,則自動添加where 56 if wheres: 57 wheres = ' where ' + wheres 58 59 # 合成sql語句 60 sql = "select %(column_name_list)s from %(table_name)s %(wheres)s" % \ 61 {'column_name_list': self.__column_name_list, 'table_name': self.__table_name, 'wheres': wheres} 62 # 初化化資料庫鏈接 63 result = self.select(sql) 64 if result: 65 return result[0] 66 return {} 67 68 def get_model_for_pk(self, pk, wheres=''): 69 """通過主鍵值獲取資料庫記錄實體""" 70 if not pk: 71 return {} 72 # 組裝查詢條件 73 wheres = '%s = %s' % (self.__pk_name, str(pk)) 74 75 return self.get_model(wheres) 76 77 def get_value(self, column_name, wheres=''): 78 """ 79 獲取指定條件的欄位值————多於條記錄時,只取第一條記錄 80 :param column_name: 單個欄位名,如:id 81 :param wheres: 查詢條件 82 :return: 7 (指定的欄位值) 83 """ 84 if not column_name: 85 return None 86 elif wheres: 87 wheres = ' where ' + wheres 88 89 sql = 'select %(column_name)s from %(table_name)s %(wheres)s limit 1' % \ 90 {'column_name': column_name, 'table_name': self.__table_name, 'wheres': wheres} 91 result = self.select(sql) 92 # 如果查詢成功,則直接返回記錄字典 93 if result: 94 return result[0].get(column_name) 95 96 def get_value_list(self, column_name, wheres=''): 97 """ 98 獲取指定條件記錄的欄位值列表 99 :param column_name: 單個欄位名,如:id 100 :param wheres: 查詢條件 101 :return: [1,3,4,6,7] 102 """ 103 if not column_name: 104 column_name = self.__pk_name 105 elif wheres: 106 wheres = ' where ' + wheres 107 108 sql = 'select array_agg(%(column_name)s) as list from %(table_name)s %(wheres)s' % \ 109 {'column_name': column_name, 'table_name': self.__table_name, 'wheres': wheres} 110 result = self.select(sql) 111 # 如果查詢失敗或不存在指定條件記錄,則直接返回初始值 112 if result and isinstance(result, list): 113 return result[0].get('list') 114 else: 115 return [] 116 117 def add_model(self, fields, returning=''): 118 """新增資料庫記錄""" 119 ### 拼接sql語句 ### 120 # 初始化變數 121 key_list = [] 122 value_list = [] 123 # 將傳入的字典參數進行處理,把欄位名生成sql插入欄位名數組和字典替換數組 124 # PS:字元串使用字典替換參數時,格式是%(name)s,這裡會生成對應的字串 125 # 比如: 126 # 傳入的字典為: {'id': 1, 'name': '名稱'} 127 # 那麼生成的key_list為:'id','name' 128 # 而value_list為:'%(id)s,%(name)s' 129 # 最終而value_list為字元串對應名稱位置會被替換成相應的值 130 for key in fields.keys(): 131 key_list.append(key) 132 value_list.append('%(' + key + ')s') 133 # 設置sql拼接字典,並將數組(lit)使用join方式進行拼接,生成用逗號分隔的字元串 134 parameter = { 135 'table_name': self.__table_name, 136 'pk_name': self.__pk_name, 137 'key_list': ','.join(key_list), 138 'value_list': ','.join(value_list) 139 } 140 # 如果有指定返回參數,則添加 141 if returning: 142 parameter['returning'] = ', ' + returning 143 else: 144 parameter['returning'] = '' 145 146 # 生成可以使用字典替換的字元串 147 sql = "insert into %(table_name)s (%(key_list)s) values (%(value_list)s) returning %(pk_name)s %(returning)s" % parameter 148 # 將生成好的字元串替字典參數值,生成最終可執行的sql語句 149 sql = sql % fields 150 151 result = self.execute(sql) 152 if result: 153 return result[0] 154 return {} 155 156 def edit(self, fields, wheres='', returning=''): 157 """批量編輯資料庫記錄""" 158 ### 拼接sql語句 ### 159 # 拼接欄位與值 160 field_list = [key + ' = %(' + key + ')s' for key in fields.keys()] 161 # 設置sql拼接字典 162 parameter = { 163 'table_name': self.__table_name, 164 'pk_name': self.__pk_name, 165 'field_list': ','.join(field_list) 166 } 167 # 如果存在更新條件,則將條件添加到sql拼接更換字典中 168 if wheres: 169 parameter['wheres'] = ' where ' + wheres 170 else: 171 parameter['wheres'] = '' 172 173 # 如果有指定返回參數,則添加 174 if returning: 175 parameter['returning'] = ', ' + returning 176 else: 177 parameter['returning'] = '' 178 179 # 生成sql語句 180 sql = "update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s" % parameter 181 sql = sql % fields 182 183 return self.execute(sql) 184 185 def edit_model(self, pk, fields, wheres='', returning=''): 186 """編輯單條資料庫記錄""" 187 if not pk: 188 return {} 189 elif wheres: 190 wheres = self.__pk_name + ' = ' + str(pk) + ' and ' + wheres 191 else: 192 wheres = self.__pk_name + ' = ' + str(pk) 193 194 return self.edit(fields, wheres, returning) 195 196 def delete(self, wheres='', returning='', is_update_cache=True): 197 """批量刪除資料庫記錄""" 198 # 如果存在條件 199 if wheres: 200 wheres = ' where ' + wheres 201 202 # 如果有指定返回參數,則添加 203 if returning: 204 returning = ', ' + returning 205 206 # 生成sql語句 207 sql = "delete from %(table_name)s %(wheres)s returning %(pk_name)s %(returning)s" % \ 208 {'table_name': self.__table_name, 'wheres': wheres, 'pk_name': self.__pk_name, 'returning': returning} 209 return self.execute(sql) 210 211 def delete_model(self, pk, wheres='', returning='', is_update_cache=True): 212 """刪除單條資料庫記錄""" 213 if not pk: 214 return {} 215 elif wheres: 216 wheres = self.__pk_name + ' = ' + str(pk) + ' and ' + wheres 217 else: 218 wheres = self.__pk_name + ' = ' + str(pk) 219 220 return self.delete(wheres, returning) 221 222 def get_list(self, column_name_list='', wheres='', page_number=None, page_size=None, orderby=None, table_name=None): 223 """ 224 獲取指定條件的資料庫記錄集 225 :param column_name_list: 查詢欄位 226 :param wheres: 查詢條件 227 :param page_number: 分頁索引值 228 :param page_size: 分頁大小, 存在值時才會執行分頁 229 :param orderby: 排序規則 230 :param table_name: 查詢數據表,多表查詢時需要設置 231 :return: 返回記錄集總數量與分頁記錄集 232 {'records': 0, 'total': 0, 'page': 0, 'rows': []} 233 """ 234 # 初始化輸出參數:總記錄數量與列表集 235 data = { 236 'records': 0, # 總記錄數 237 'total': 0, # 總頁數 238 'page': 1, # 當前頁面索引 239 'rows': [], # 查詢結果(記錄列表) 240 } 241 # 初始化查詢數據表名稱 242 if not table_name: 243 table_name = self.__table_name 244 # 初始化查詢欄位名 245 if not column_name_list: 246 column_name_list = self.__column_name_list 247 # 初始化查詢條件 248 if wheres: 249 # 如果是字元串,表示該查詢條件已組裝好了,直接可以使用 250 if isinstance(wheres, str): 251 wheres = 'where ' + wheres 252 # 如果是list,則表示查詢條件有多個,可以使用join將它們用and方式組合起來使用 253 elif isinstance(wheres, list): 254 wheres = 'where ' + ' and '.join(wheres) 255 # 初始化排序 256 if not orderby: 257 orderby = self.__pk_name + ' desc' 258 # 初始化分頁查詢的記錄區間 259 paging = '' 260 261 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db: 262 ############################################################# 263 # 判斷是否需要進行分頁 264 if not page_size is None: 265 ### 執行sql,獲取指定條件的記錄總數量 266 sql = 'select count(1) as records from %(table_name)s %(wheres)s ' % \ 267 {'table_name': table_name, 'wheres': wheres} 268 result = db.execute(sql) 269 # 如果查詢失敗或不存在指定條件記錄,則直接返回初始值 270 if not result or result[0]['records'] == 0: 271 return data 272 273 # 設置記錄總數量 274 data['records'] = result[0].get('records') 275 276 ######################################################### 277 ### 設置分頁索引與頁面大小 ### 278 if page_size <= 0: 279 page_size = 10 280 # 計算總分頁數量:通過總記錄數除於每頁顯示數量來計算總分頁數量 281 if data['records'] % page_size == 0: 282 page_total = data['records'] // page_size 283 else: 284 page_total = data['records'] // page_size + 1 285 # 判斷頁碼是否超出限制,超出限制查詢時會出現異常,所以將頁面索引設置為最後一頁 286 if page_number < 1 or page_number > page_total: 287 page_number = page_total 288 # 記錄總頁面數量 289 data['total'] = page_total 290 # 記錄當前頁面值 291 data['page'] = page_number 292 # 計算當前頁面要顯示的記錄起始位置(limit指定的位置) 293 record_number = (page_number - 1) * page_size 294 # 設置查詢分頁條件 295 paging = ' limit ' + str(page_size) + ' offset ' + str(record_number) 296 ############################################################# 297 298 ### 按條件查詢資料庫記錄 299 sql = "select %(column_name_list)s from %(table_name)s %(wheres)s order by %(orderby)s %(paging)s" % \ 300 {'column_name_list': column_name_list, 301 'table_name': table_name, 302 'wheres': wheres, 303 'orderby': orderby, 304 'paging': paging} 305 result = db.execute(sql) 306 if result: 307 data['rows'] = result 308 # 不需要分頁查詢時,直接在這裡設置總記錄數 309 if page_size is None: 310 data['records'] = len(result) 311 312 return data 313 314 def get_count(self, wheres=''): 315 """獲取指定條件記錄數量""" 316 if wheres: 317 wheres = ' where ' + wheres 318 sql = 'select count(1) as total from %(table_name)s %(wheres)s ' % \ 319 {'table_name': self.__table_name, 'wheres': wheres} 320 result = self.select(sql) 321 # 如果查詢存在記錄,則返回true 322 if result: 323 return result[0].get('total') 324 return 0 325 326 def get_sum(self, fields, wheres): 327 """獲取指定條件記錄數量""" 328 sql = 'select sum(%(fields)s) as total from %(table_name)s where %(wheres)s ' % \ 329 {'table_name': self.__table_name, 'wheres': wheres, 'fields': fields} 330 result = self.select(sql) 331 # 如果查詢存在記錄,則返回true 332 if result and result[0].get('total'): 333 return result[0].get('total') 334 return 0 335 336 def get_min(self, fields, wheres): 337 """獲取該列記錄最小值""" 338 sql = 'select min(%(fields)s) as min from %(table_name)s where %(wheres)s ' % \ 339 {'table_name': self.__table_name, 'wheres': wheres, 'fields': fields} 340 result = self.select(sql) 341 # 如果查詢存在記錄,則返回true 342 if result and result[0].get('min'): 343 return result[0].get('min') 344 345 def get_max(self, fields, wheres): 346 """獲取該列記錄最大值""" 347 sql = 'select max(%(fields)s) as max from %(table_name)s where %(wheres)s ' % \ 348 {'table_name': self.__table_name, 'wheres': wheres, 'fields': fields} 349 result = self.select(sql) 350 # 如果查詢存在記錄,則返回true 351 if result and result[0].get('max'): 352 return result[0].get('max') 353 354 #####################################################################View Code
大家只要掌握了ORM簡單的組合sql方法,就可以自由發揮,根據自己的需要去創建不同的方法了,也可以隨意更換mysql、mssql等資料庫。
當然,這隻是最簡單的ORM方式,提交欄位參數和條件參數時,它不會自動分辨欄位的類型,不會自動初始化預設值,如果想讓它變的更加強大,還需要做更多的改造與處理,這樣做的話它也會跟著變的更加複雜和難懂,性能也會跟著下降。不過當前功能對於多數項目來說,已經足夠使用了。大家如果有需要可以自行研究進行擴展。
在日常操作中,獲取指定記錄實體是最常見使用最頻繁的操作,為了減少對資料庫的查詢,我們可以將ORM與Nosql結合起來,提升ORM的操作性能,當然如果你不想使用nosql緩存,也可以直接跳過本章節。
使用Nosql,首先我們需要一個鏈接Nosql的配置文件,用它來存儲Nosql的服務地址、埠、密碼等參數
在config文件夾中我們創建redis_config.py配置文件
#!/usr/bin/env python #