首页 > 数据库 >python - sqlachemy

python - sqlachemy

时间:2024-12-05 17:53:58浏览次数:6  
标签:sqlachemy DBSession rollback python text session print id

这是一个 ORM 框架(已经包含连接池)

安装插件

pip install pymysql sqlalchemy

参数配置


from sqlalchemy import create_engine, text

# 定义数据库连接字符串
DATABASE_URI = 'mysql+pymysql://{username}:{password}@{host}:{port}/{dbname}?charset=utf8mb4'

# 替换为你的数据库用户名、密码、主机、端口和数据库名
USERNAME = 'root'
PASSWORD = 'root'
HOST = 'localhost'
PORT = '3306'
DBNAME = 'med'

# 创建数据库引擎,使用连接池
engine = create_engine(
    DATABASE_URI.format(
        username=USERNAME,
        password=PASSWORD,
        host=HOST,
        port=PORT,
        dbname=DBNAME
    ),
    echo=False,  # 如果设置为True,SQLAlchemy将打印所有执行的SQL语句,通常用于调试
    pool_size=10,  # 连接池大小
    max_overflow=20,  # 超过连接池大小外最多创建的连接数
    pool_timeout=30,  # 连接池中没有线程可用时,在抛出异常前等待的时间
    pool_recycle=3600  # 多少秒之后对连接进行一次回收(重置)
)

# do a test
with engine.connect() as con:
    rs = con.execute(text('SELECT 1'))
    rs.fetchone()
    print('create engine succeed!')

数据库会话 session

数据库会话(session)可分为:普通会话、线程安全的会话。

线程安全的会话,已经实现了 threadlocal 功能,不同线程之间彼此隔离。


from sqlalchemy.orm import sessionmaker, scoped_session

# 普通 session
Session = sessionmaker(bind=engine)
# 线程安全的 session
DBSession = scoped_session(Session)

测试代码如下,运行后可以看到,两个通过 DBSession 创建的 session,他们的 id 是完全一致的。

print(id(DBSession()))
print(id(DBSession()))

session = Session()
print(id(session))

执行SQL

session = Session()
print(id(session))

# 定义SQL语句
sql = "SELECT * FROM `t_temp` WHERE (`id`= :id) LIMIT 1"

# 执行SQL语句
result = session.execute(text(sql), {'id': 18})

# 处理结果
for row in result:
    print(row)

# 关闭会话
session.close()

事务注解

sqlalchemy 没有提供注解事务,不过我们可以参考 spring 中的做法,自己做一个。

def transactional(rollback: type = Exception):
    r"""
    注解式事务

    用法类似于 spring 环境下的 @Transactional 注解

    注意: 事务控制在 session 级别,不兼容事务嵌套的场景

    推荐: 如果遇到很复杂的事务嵌套,显式调用 session,手动控制事务
	
	改进方案:如果想进行改造,允许事务嵌套,可以通过 save-point 调整当前代码

    :param rollback: 指定触发回滚的异常类型
    :return: 装饰器函数
    """

    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

测试函数如下

@transactional()
def debug():
    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'})

    result = session.execute(text("SELECT * FROM `t_temp` WHERE (`id`= :id) LIMIT 1"), {'id': 18})

    # 处理结果
    for row in result:
        print(row)

    raise ValueError('db error')

保存点 save-point

和游戏的保存点概念一致,在一个事务中,可以设置多个保存点,出现异常,可以按需选择保存点进行回退。

保存点用于处理复杂的事务控制,通常情况下,整个职业生涯都不会直接接触这些代码。

session = DBSession()
connection = session.connection()
savepoint = connection.begin_nested()
try:
	# do sth.
	savepoint.commit()
except Exception as e:
	if savepoint:
		savepoint.rollback()

ORM 相关内容

因为只是想要连接池,相关需求暂无,以后再做补充……

标签:sqlachemy,DBSession,rollback,python,text,session,print,id
From: https://www.cnblogs.com/chenss15060100790/p/18589082

相关文章

  • python - logger
    日志配置importloggingfromlogging.handlersimportTimedRotatingFileHandler#NOTSET<DEBUG<INFO<WARNING<ERROR<CRITICAL#创建一个loggerlogger=logging.getLogger('default')logger.setLevel(logging.DEBUG)#日志输出格式formatte......
  • python - mysql交互
    python与mysql交互,能找到两个库pymysql和mysql-connector-python因为两个都是基于DB-API2.0标准‌,使用上差别并不大,区别就是mysql-connector-python是由Oracle官方提供,性能可能会好一些。安装依赖pipinstallmysql-connector-python事务(update)importmysql.co......
  • python - with
    with用法很像java中的try(){}代码块,调用对象之后,会自动执行资源释放函数。在python中,要使用with语句,需要实现两个特殊方法:__enter__和__exit__。比如:classSession:def__enter__(self):print("Enteringcontext")returnself#返回上下文管......
  • python - 安装pip插件
    功能:安装各种插件,功能与maven类似windows环境下,安装包中自带这个插件,检查路径./Scripts,如果包含pip.exe文件,则无须安装安装官网:https://pip.pypa.io/en/stable/installation/Downloadthescript,fromhttps://bootstrap.pypa.io/get-pip.py.Openaterminal/command......
  • OpenCV实现文档扫描OCR识别(基于Python + OpenCV,含完整代码)
    OpenCV文档扫描OCR识别一、引言在当今数字化时代,文档处理的自动化需求日益增长。文档扫描OCR(OpticalCharacterRecognition,光学字符识别)技术成为了将纸质文档转换为可编辑电子文本的关键手段。通过Python与OpenCV库的结合,我们能够实现高效、准确的文档扫描OCR识别。这一......
  • python学opencv|读取图像(二)保存彩色图像
    【1】引言前序学习过程中,已经掌握了读取图像的基本操作,对三个函数的功能有了基本了解:cv.imread()、cv.imshow()、cv.imwrite()学习文章链接为:python学opencv|读取图像-CSDN博客不过这篇文章里,我们获得的图像是灰度图。如果需要彩色图,那又如何处理,这就是本次课程的目的。......
  • Python 装饰器
    基本概念装饰器是一种强大的工具,允许你在不修改原有函数或方法代码的情况下,给其增加额外的功能。装饰器本质上是一个函数,它接受一个函数作为参数并返回一个新的函数。基本语法defmy_decorator(func):defwrapper(*args,**kwargs):print('函数运行之前')......
  • (2024最新毕设合集)基于SSM的河北省博物馆管理系统-02350|可做计算机毕业设计JAVA、PHP
    目 录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2 河北省博物馆管理系统系统分析2.1可行性分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3操作可行性分析2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析......
  • 基于python爬虫的豆瓣电影推荐系统
    私信我获取源码和万字论文,制作不易,感谢点赞支持。目  录1团队建设1.1团队的任务和目标1.2团队制度1.3团队任务分配1.4项目进度安排2需求分析2.1国内外研究现状2.2研究背景与意义2.3功能分析和性能分析2.4用例图2.5类图2.6系统E-R图......
  • 停车场车位识别:基于Python和OpenCV(含完整代码)
    停车场车位识别:基于Python和OpenCV一、引言在现代城市生活中,停车场的管理效率对于解决交通拥堵和提升用户体验至关重要。停车场车位识别技术作为智能化停车场管理的核心部分,能够自动检测和识别停车场中的空闲车位,为车主提供便捷的停车引导,同时也便于停车场管理者进行资源......