對SQLAlchemy進行改寫模软×莆遥可直接拿到別的項目中使用

  • model這一塊用的是SQLAlchemy
  • 繼承重寫Query查詢

第一個:Query的改寫

# 所謂的改寫并不是在源碼中改寫,而是繼承之后重寫這個方法
# 在flask_app>orm>base.py 
from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy, BaseQuery
from sqlalchemy import inspect, Column, Integer, SmallInteger, orm
from contextlib import contextmanager

from common.error import NotFoundError
from flask_app.orm import transfer

class SQLAlchemy(_SQLAlchemy):
    @contextmanager
    def auto_commit(self):
        try:
            yield
            self.session.commit()
        except Exception as e:
            db.session.rollback()
            raise e

class Query(BaseQuery):
    def filter_by(self, **kwargs):
        # 這個是每個model中都加入了status拧咳。只有等于0才會被找到
        if 'status' not in kwargs.keys():
            kwargs['status'] = 0
        return super(Query, self).filter_by(**kwargs)

    def get_or_404(self, ident):
        rv = self.get(ident)
        if not rv:
            raise NotFoundError(msg="數(shù)據(jù)不存在")
        return rv

    def first_or_404(self):
        rv = self.first()
        if not rv:
            raise NotFoundError(msg="數(shù)據(jù)不存在")
        return rv

db = SQLAlchemy(session_options={'autocommit': True},query_class=Query)

# 這樣用的話  找不到直接報出異常伯顶,很好使用

第二個:Model改寫

class BaseModel(db.Model):
    __abstract__ = True

    def insert(self):
        self._before_insert()
        self.try_to_add_ip()
        self.try_to_add_device_info()
        db.session.add(self)
        db.session.flush()
        self._after_insert()
        return self

    def update(self):
        self._before_update()
        db.session.merge(self)
        db.session.flush()
        self._after_update()
        return self

    def delete(self):
        self._before_delete()
        db.session.delete(self)
        db.session.flush()
        self._after_delete()

    def _before_insert(self):
        pass

    def _after_insert(self):
        pass

    def _before_update(self):
        pass

    def _after_update(self):
        pass

    def _before_delete(self):
        pass

    def _after_delete(self):
        pass

    @classmethod
    def load_all_data_field(cls):
        """
        獲取類自身所有數(shù)據(jù)表映射字段名
        :return:
        """
        if hasattr(cls, '__table__'):
            return [c.name for c in cls.__table__.columns]

    def try_to_add_ip(self):
        ip_column = 'ip'
        # 檢查是否有ip這個field,如果有并且沒有值,則從flask request對象里面取
        if ip_column in self.load_all_data_field():
            ip_val = getattr(self,ip_column)
            if not ip_val:
                from flask import request
                setattr(self,ip_column,request.headers.get('X-Forwarded-For', None) or request.remote_addr)

    def try_to_add_device_info(self):
        device_infos = ['imei', 'mac']
        # 檢查是否有ip這個field慨仿,如果有并且沒有值壹瘟,則從flask request對象里面取
        for info in device_infos:
            if info in self.load_all_data_field():
                info_val = getattr(self, info)
                if not info_val:
                    from flask import request

                    info_val = request.args.get(info, "")
                    if info_val:
                        setattr(self, info, info_val)

    def to_dict(self, without=(), include=()):
        """
        主要是將model轉(zhuǎn)換為字典返回
        """
        return transfer.orm_obj2dict(self, without, include)

    def update_from_json(self,json_str):
        """
        接受json_str更新原本信息
        """
        return transfer.json_up_orm_obj(json_str,self)

    @classmethod
    def from_dict(cls, dic):
        return transfer.dict2obj(dic, cls)

    def __repr__(self):
        return self.to_json()

    def to_json(self, without=(), include=()):
        return transfer.orm_obj2json(self, without, include)

    def save(self):
        if self.id:
            self.update()
        else:
            self.insert()


class MixinJSONSerializer:
    @orm.reconstructor
    def init_on_load(self):
        self._fields = []
        # self._include = []
        self._exclude = []

        self._set_fields()
        self.__prune_fields()

    def _set_fields(self):
        pass

    def __prune_fields(self):
        columns = inspect(self.__class__).columns
        if not self._fields:
            all_columns = set(columns.keys())
            self._fields = list(all_columns - set(self._exclude))

    def hide(self, *args):
        for key in args:
            self._fields.remove(key)
        return self

    def keys(self):
        return self._fields

    def __getitem__(self, key):
        return getattr(self, key)
  • BaseModel 和MixinJSONSerializer 都是可用于model繼承的
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市掐暮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌政钟,老刑警劉巖路克,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異养交,居然都是意外死亡精算,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門碎连,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灰羽,“玉大人,你說我怎么就攤上這事×溃” “怎么了玫镐?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長怠噪。 經(jīng)常有香客問我恐似,道長,這世上最難降的妖魔是什么傍念? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任矫夷,我火速辦了婚禮,結(jié)果婚禮上捂寿,老公的妹妹穿的比我還像新娘口四。我一直安慰自己,他們只是感情好秦陋,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布蔓彩。 她就那樣靜靜地躺著,像睡著了一般驳概。 火紅的嫁衣襯著肌膚如雪赤嚼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天顺又,我揣著相機與錄音更卒,去河邊找鬼。 笑死稚照,一個胖子當著我的面吹牛蹂空,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播果录,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼上枕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弱恒?” 一聲冷哼從身側(cè)響起辨萍,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎返弹,沒想到半個月后锈玉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡义起,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年拉背,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片默终。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡椅棺,死狀恐怖抡诞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情土陪,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布肴熏,位于F島的核電站鬼雀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛙吏。R本人自食惡果不足惜源哩,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸦做。 院中可真熱鬧励烦,春花似錦、人聲如沸泼诱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽治筒。三九已至屉栓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耸袜,已是汗流浹背友多。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留堤框,地道東北人域滥。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像蜈抓,于是被迫代替她去往敵國和親启绰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 29,334評論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,090評論 1 32
  • 22年12月更新:個人網(wǎng)站關(guān)停资昧,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,165評論 22 257
  • orm操作是所有完整軟件中后端處理最重要的一部分酬土,主要完成了后端程序和數(shù)據(jù)庫之間的數(shù)據(jù)同步和持久化的操作,本文基于...
    大熊_7d48閱讀 5,002評論 1 13
  • 交往格带,交往撤缴,好過一杯醇釀。太陽關(guān)切高粱叽唱,神采飛揚亮光屈呕。光亮,光亮棺亭,黑夜來臨坦蕩虎眨。
    木貞ma閱讀 166評論 0 1