最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

這里只是給出一個思路,或許對于未來解決問題有一些參考意義。

仿 JAP 的寫法

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

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

潛在風險:代碼檢測的時候,可能會被誤判,因為我們定義了一大堆空的函數(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ù)庫連接字符串
DATABASE_URI = 'mysql+pymysql://{username}:{password}@{host}:{port}/{dbname}?charset=utf8mb4'
# 替換為你的數(shù)據(jù)庫用戶名、密碼、主機、端口和數(shù)據(jù)庫名
USERNAME = 'root'
PASSWORD = 'root'
HOST = 'localhost'
PORT = '3306'
DBNAME = 'med'
# 創(chuàng)建數(shù)據(jù)庫引擎,使用連接池
engine = create_engine(
    DATABASE_URI.format(
        username=USERNAME,
        password=PASSWORD,
        host=HOST,
        port=PORT,
        dbname=DBNAME
    ),
    echo=False,  # 如果設(shè)置為True,SQLAlchemy將打印所有執(zhí)行的SQL語句,通常用于調(diào)試
    pool_size=10,  # 連接池大小
    max_overflow=20,  # 超過連接池大小外最多創(chuàng)建的連接數(shù)
    pool_timeout=30,  # 連接池中沒有線程可用時,在拋出異常前等待的時間
    pool_recycle=3600  # 多少秒之后對連接進行一次回收(重置)
)
# 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ù)庫連接
#     connection = session.connection()
#     savepoint = connection.begin_nested()
#     print(savepoint)
def getEffectRows(result: Result) -> int:
    r"""
    獲取受影響行數(shù)
    這里有點問題:源碼部分 rowcount 是一個 callable,但實際應(yīng)該是 int;
    這里繞一點,確保不會出問題,如果返回 -1,說明出現(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í)行一條查詢語句
    :param sql: 查詢語句
    :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í)行一個查詢
    :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í)行一個查詢
    :param sql: sql 執(zhí)行語句
    :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 級別,不能兼容事務(wù)嵌套的場景(理想狀態(tài)下,應(yīng)當通過 save-point 實現(xiàn))
    推薦: 如果遇到很復雜的事務(wù)嵌套,顯式調(diào)用 session,手動控制事務(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"""
    測試注解式事務(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"""
    測試封裝過的函數(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • transform python環(huán)境快速配置方法

    transform python環(huán)境快速配置方法

    經(jīng)常在數(shù)據(jù)開發(fā)中需要搞udf,最近發(fā)現(xiàn)transform更加方便易用,但是經(jīng)常會涉及到集群python版本不一、包不全或者部分機器上沒有安裝python。這篇文章主要介紹了transform python環(huán)境快速配置方法,需要的朋友可以參考下
    2018-09-09
  • 深入解析Python中的__builtins__內(nèi)建對象

    深入解析Python中的__builtins__內(nèi)建對象

    __builtins__ 是內(nèi)建模塊__builtin__中的對象,使用Python中的內(nèi)建函數(shù)時會通過__builtins__引導,這里我們就來深入解析Python中的__builtins__內(nèi)建對象,需要的朋友可以參考下
    2016-06-06
  • pytorch中forwod函數(shù)在父類中的調(diào)用方式解讀

    pytorch中forwod函數(shù)在父類中的調(diào)用方式解讀

    這篇文章主要介紹了pytorch中forwod函數(shù)在父類中的調(diào)用方式解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • python基礎(chǔ)之變量和數(shù)據(jù)類型

    python基礎(chǔ)之變量和數(shù)據(jù)類型

    這篇文章主要介紹了python的變量和數(shù)據(jù)類型,實例分析了Python中返回一個返回值與多個返回值的方法,需要的朋友可以參考下
    2021-10-10
  • Python 字符串操作詳情

    Python 字符串操作詳情

    這篇文章主要介紹了Python 字符串操作,所謂字符串,就是由0個或者多個字符組成的有限序列,字符串的字符可以是特殊符號、英文字母、中文字符、日文的平假名或片假名、希臘字母、Emoji字符等等。下面我們大家一起來學習文章詳細內(nèi)容吧
    2021-11-11
  • selenium設(shè)置proxy、headers的方法(phantomjs、Chrome、Firefox)

    selenium設(shè)置proxy、headers的方法(phantomjs、Chrome、Firefox)

    這篇文章主要介紹了selenium設(shè)置proxy、headers的方法(phantomjs、Chrome、Firefox),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • python如何把字符串類型list轉(zhuǎn)換成list

    python如何把字符串類型list轉(zhuǎn)換成list

    這篇文章主要介紹了python如何吧字符串類型list轉(zhuǎn)換成list,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Python構(gòu)建一個簡單的數(shù)據(jù)處理流水線

    Python構(gòu)建一個簡單的數(shù)據(jù)處理流水線

    數(shù)據(jù)處理流水線是數(shù)據(jù)分析和工程中非常常見的概念,通過流水線的設(shè)計,可以將數(shù)據(jù)的采集、處理、存儲等步驟連接起來,實現(xiàn)自動化的數(shù)據(jù)流,使用Python構(gòu)建一個簡單的數(shù)據(jù)處理流水線(Data?Pipeline),一步步構(gòu)建流程,并附上流程圖來幫助你更好地理解數(shù)據(jù)流的工作方式
    2024-12-12
  • Python實現(xiàn)批量CSV轉(zhuǎn)Excel的高性能處理方案

    Python實現(xiàn)批量CSV轉(zhuǎn)Excel的高性能處理方案

    在日常辦公中,我們經(jīng)常需要將CSV格式的數(shù)據(jù)轉(zhuǎn)換為Excel文件,本文將介紹一個基于Python的高性能解決方案,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-09-09
  • Pycharm 創(chuàng)建 Django admin 用戶名和密碼的實例

    Pycharm 創(chuàng)建 Django admin 用戶名和密碼的實例

    今天小編就為大家分享一篇Pycharm 創(chuàng)建 Django admin 用戶名和密碼的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05

最新評論

团风县| 尼勒克县| 修水县| 广饶县| 房产| 晋中市| 会泽县| 来宾市| 望谟县| 玉门市| 裕民县| 安宁市| 兰溪市| 穆棱市| 泽普县| 大姚县| 新泰市| 新建县| 汉沽区| 盐池县| 南康市| 石河子市| 光泽县| 剑川县| 忻城县| 来安县| 荣昌县| 鹿泉市| 吉林省| 兴仁县| 藁城市| 芷江| 龙江县| 崇阳县| 泰来县| 莎车县| 舒城县| 九龙县| 西充县| 铜梁县| 新平|