欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python?-?sqlachemy另類用法思路詳解

 更新時(shí)間:2024年12月06日 08:54:49   作者:瘋狂的妞妞  
這篇文章主要介紹了python?-?sqlachemy另類用法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

這里只是給出一個(gè)思路,或許對(duì)于未來(lái)解決問(wèn)題有一些參考意義。

仿 JAP 的寫法

這種寫法很像 java 環(huán)境中的 JPA,如果引入模版引擎,則可以大幅增強(qiáng)實(shí)用性。

但是,在 python 環(huán)境中,這不符合主流的 ORM 框架。

潛在風(fēng)險(xiǎn):代碼檢測(cè)的時(shí)候,可能會(huì)被誤判,因?yàn)槲覀兌x了一大堆空的函數(shù)。

# 注解式事務(wù) start ---------------------------------------------
@update(sql='UPDATE `t_temp` SET `desc`= :desc WHERE (`id`= :id) LIMIT 1')
def modify(params: dict = None) -> int:
    pass
@query(sql='SELECT * FROM `t_temp` WHERE (`id`= :id) LIMIT 1', result_type=dict)
def queryById(params: dict = None) -> list:
    pass
@query(sql='SELECT * FROM `t_temp` WHERE (`id`= :id) LIMIT 1', result_type=dict)
def queryById2(id: int) -> list:
    pass
@transactional()
def test_annotation():
    ret = modify({'id': 18, 'desc': 'OR 1=1'})
    print(ret)
    result = queryById2(18)
    print(result)

代碼封裝

import inspect
import logger_factory
import typing
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.engine import Result, CursorResult
logger = logger_factory.get_logger()
# 定義數(shù)據(jù)庫(kù)連接字符串
DATABASE_URI = 'mysql+pymysql://{username}:{password}@{host}:{port}/{dbname}?charset=utf8mb4'
# 替換為你的數(shù)據(jù)庫(kù)用戶名、密碼、主機(jī)、端口和數(shù)據(jù)庫(kù)名
USERNAME = 'root'
PASSWORD = 'root'
HOST = 'localhost'
PORT = '3306'
DBNAME = 'med'
# 創(chuàng)建數(shù)據(jù)庫(kù)引擎,使用連接池
engine = create_engine(
    DATABASE_URI.format(
        username=USERNAME,
        password=PASSWORD,
        host=HOST,
        port=PORT,
        dbname=DBNAME
    ),
    echo=False,  # 如果設(shè)置為True,SQLAlchemy將打印所有執(zhí)行的SQL語(yǔ)句,通常用于調(diào)試
    pool_size=10,  # 連接池大小
    max_overflow=20,  # 超過(guò)連接池大小外最多創(chuàng)建的連接數(shù)
    pool_timeout=30,  # 連接池中沒(méi)有線程可用時(shí),在拋出異常前等待的時(shí)間
    pool_recycle=3600  # 多少秒之后對(duì)連接進(jìn)行一次回收(重置)
)
# do a test
with engine.connect() as con:
    rs = con.execute(text('SELECT 1'))
    rs.fetchone()
    logger.debug('create engine succeed!')
# session-maker
Session = sessionmaker(bind=engine)
# thread safe session-maker
DBSession = scoped_session(Session)
# with Session() as session:
#     # 獲取數(shù)據(jù)庫(kù)連接
#     connection = session.connection()
#     savepoint = connection.begin_nested()
#     print(savepoint)
def getEffectRows(result: Result) -> int:
    r"""
    獲取受影響行數(shù)
    這里有點(diǎn)問(wèn)題:源碼部分 rowcount 是一個(gè) callable,但實(shí)際應(yīng)該是 int;
    這里繞一點(diǎn),確保不會(huì)出問(wèn)題,如果返回 -1,說(shuō)明出現(xiàn)了意料之外的情況
    :param result: 結(jié)果集
    :return: 受影響行數(shù)
    """
    if isinstance(result, CursorResult):
        effect_row = result.rowcount
        if isinstance(effect_row, int):
            return effect_row
        if callable(effect_row):
            return effect_row()
    return -1
def resultAsDict(result: Result) -> list:
    r"""
    將查詢結(jié)果轉(zhuǎn)換為 dict-list
    :param result: 結(jié)果集
    :return: dict 列表
    """
    keys = result.keys()
    ret = list()
    for item in result.fetchall():
        ret.append(dict(zip(keys, item)))
    return ret
def execute(sql: str, params: dict = None) -> Result:
    r"""
    執(zhí)行一條查詢語(yǔ)句
    :param sql: 查詢語(yǔ)句
    :param params: 參數(shù)
    :return: 結(jié)果集
    """
    if sql is None:
        raise ValueError('sql cannot be None')
    logger.debug('execute sql: ' + sql)
    logger.debug('parameter  : ' + str(params))
    return DBSession().execute(text(sql), params)
def executeQuery(sql: str, params: dict = None, result_type: type = tuple) -> typing.Sequence:
    r"""
    執(zhí)行一個(gè)查詢
    :param sql: sql
    :param params: dict
    :param result_type: 結(jié)果集類型,可選:tuple、dict
    :return: 序列
    """
    result = execute(sql, params)
    if result_type == dict:
        return resultAsDict(result)
        pass
    # default return_type tuple-list
    return result.fetchall()
def executeUpdate(sql: str, params: dict = None) -> int:
    r"""
    執(zhí)行一個(gè)查詢
    :param sql: sql 執(zhí)行語(yǔ)句
    :param params: dict 查詢參數(shù)
    :return: 受影響行數(shù)
    """
    result = execute(sql, params)
    return getEffectRows(result)
def transactional(rollback: type = Exception):
    r"""
    注解式事務(wù)
    用法類似于 spring 環(huán)境下的 @Transactional 注解
    注意: 事務(wù)控制在 session 級(jí)別,不能兼容事務(wù)嵌套的場(chǎng)景(理想狀態(tài)下,應(yīng)當(dāng)通過(guò) save-point 實(shí)現(xiàn))
    推薦: 如果遇到很復(fù)雜的事務(wù)嵌套,顯式調(diào)用 session,手動(dòng)控制事務(wù)
    :param rollback: 指定觸發(fā)回滾的異常類型
    :return: 裝飾器函數(shù)
    """
    def decorator(func):
        def call(*args, **kwargs):
            session = None
            try:
                session = DBSession()
                ret = func(*args, **kwargs)
                session.commit()
                return ret
            except rollback as e:
                if session:
                    session.rollback()
                logger.exception(f'transaction exception, rollback: {str(e)}')
                raise
            finally:
                if session:
                    session.close()
        return call
    return decorator
    pass
def update(sql: str = None):
    r"""
    注解式查詢,E.G.::
        @update(sql='UPDATE `t_temp` SET `desc`= :desc WHERE (`id`= :id) LIMIT 1')
        def modify(params: dict = None) -> int:
            pass
    :param sql: 要執(zhí)行的 sql
    :return: decorator
    """
    def decorator(func):
        def call(*args, **kwargs):
            result = execute(sql, args[0])
            return getEffectRows(result)
        return call
    return decorator
    pass
def query(sql: str = None, result_type: type = tuple):
    r"""
    注解式查詢,E.G.::
    E.G.::
        @query(sql='SELECT * FROM `t_temp` WHERE (`id`= :id) LIMIT 1', result_type=dict)
        def queryById2(id: int) -> list:
            pass
    :param sql: 要執(zhí)行的 sql
    :param result_type: 結(jié)果集類型,可選:tuple、dict
    :return:  decorator
    """
    def decorator(func):
        def call(*args, **kwargs):
            if sql is None:
                raise ValueError('sql cannot be None')
            first = args[0]
            if isinstance(first, dict):
                result = DBSession().execute(text(sql), args)
            else:
                names = inspect.signature(func).parameters.values()
                params = dict()
                for idx, name in enumerate(names):
                    params[name.name] = args[idx]
                print(params)
                result = DBSession().execute(text(sql), params)
            if result_type == dict:
                keys = result.keys()
                ret = list()
                for item in result.fetchall():
                    ret.append(dict(zip(keys, item)))
                return ret
                # default return_type tuple
                pass
            return result.fetchall()
        return call
    return decorator
    pass
@transactional()
def test_transaction():
    r"""
    測(cè)試注解式事務(wù)
    :return: None
    """
    session = DBSession()
    session.execute(text("UPDATE `t_temp` SET `desc`= :desc WHERE (`id`= :id) LIMIT 1"), {'id': 18, 'desc': 'OR 1=3'})
    session.execute(text("UPDATE `t_temp` SET `desc`= :desc WHERE (`id`= :id) LIMIT 1"), {'id': 18, 'desc': 'OR 1=4'})
    # raise exception
    raise SyntaxError('Syntax error')
@transactional()
def test_api():
    r"""
    測(cè)試封裝過(guò)的函數(shù)
    :return: None
    """
    execute("UPDATE `t_temp` SET `desc`= :desc WHERE (`id`= :id) LIMIT 1", {'id': 18, 'desc': 'OR 1=1'})
    execute("UPDATE `t_temp` SET `desc`= :desc WHERE (`id`= :id) LIMIT 1", {'id': 18, 'desc': 'OR 1=2'})
    # raise exception
    raise SyntaxError('Syntax error')

到此這篇關(guān)于python - sqlachemy另類用法的文章就介紹到這了,更多相關(guān)python sqlachemy另類用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何利用python?turtle繪圖自定義畫布背景顏色

    如何利用python?turtle繪圖自定義畫布背景顏色

    Turtle庫(kù)是Python語(yǔ)言中一個(gè)很流行的繪制圖像的函數(shù)庫(kù),想象一個(gè)小烏龜,在一個(gè)橫軸為x、縱軸為y的坐標(biāo)系原點(diǎn),(0,0)位置開(kāi)始,這篇文章主要給大家介紹了關(guān)于如何利用python?turtle繪圖自定義畫布背景顏色的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • pytorch DataLoader的num_workers參數(shù)與設(shè)置大小詳解

    pytorch DataLoader的num_workers參數(shù)與設(shè)置大小詳解

    這篇文章主要介紹了pytorch DataLoader的num_workers參數(shù)與設(shè)置大小詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python使用Streamlit庫(kù)制作Web可視化頁(yè)面

    python使用Streamlit庫(kù)制作Web可視化頁(yè)面

    一談到Web頁(yè)面,可能大家首先想到就是HTML,CSS或JavaScript。 本次小F就給大家介紹一下如何用Python制作一個(gè)數(shù)據(jù)可視化網(wǎng)頁(yè),使用到的是Streamlit庫(kù)。輕松的將一個(gè)Excel數(shù)據(jù)文件轉(zhuǎn)換為一個(gè)Web頁(yè)面,提供給所有人在線查看。
    2021-05-05
  • python3.9之你應(yīng)該知道的新特性詳解

    python3.9之你應(yīng)該知道的新特性詳解

    這篇文章主要介紹了python3.9之你應(yīng)該知道的新特性詳解,需要的朋友可以參考下
    2021-04-04
  • Python 比較兩個(gè)數(shù)組的元素的異同方法

    Python 比較兩個(gè)數(shù)組的元素的異同方法

    下面小編就為大家?guī)?lái)一篇Python 比較兩個(gè)數(shù)組的元素的異同方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 神經(jīng)網(wǎng)絡(luò)相關(guān)之基礎(chǔ)概念的講解

    神經(jīng)網(wǎng)絡(luò)相關(guān)之基礎(chǔ)概念的講解

    今天小編就為大家分享一篇關(guān)于神經(jīng)網(wǎng)絡(luò)相關(guān)之基礎(chǔ)概念的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • Python實(shí)現(xiàn)自動(dòng)化處理PDF文件的方法詳解

    Python實(shí)現(xiàn)自動(dòng)化處理PDF文件的方法詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Python完成簡(jiǎn)單的PDF文件處理操作,如PDF文件的批量合并、拆分、加密以及添加水印等,需要的可以參考一下
    2022-09-09
  • 詳解python3中zipfile模塊用法

    詳解python3中zipfile模塊用法

    本篇文章給大家分享了關(guān)于python3中zipfile模塊的詳細(xì)用法以及技術(shù)難點(diǎn)解析,有興趣的朋友跟著學(xué)習(xí)下吧。
    2018-06-06
  • 關(guān)于python的縮進(jìn)規(guī)則的知識(shí)點(diǎn)詳解

    關(guān)于python的縮進(jìn)規(guī)則的知識(shí)點(diǎn)詳解

    在本篇文章里小編給大家整理了關(guān)于python的縮進(jìn)規(guī)則的知識(shí)點(diǎn)詳解,有興趣的朋友們可以學(xué)習(xí)下。
    2020-06-06
  • python繪制淺色范圍曲線的示例代碼

    python繪制淺色范圍曲線的示例代碼

    這篇文章主要介紹了python繪制淺色范圍曲線,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10

最新評(píng)論