【Python系列】SQLAlchemy 基本介绍

news2024/11/13 12:42:22

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术,jvm,并发编程 redis,kafka,Spring,微服务等
    • 常用开发工具系列:常用的开发工具,IDEA,Mac,Alfred,Git,typora 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 新空间代码工作室:提供各种软件服务,承接各种毕业设计,毕业论文等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

    • 一.基础介绍
      • 1. SQLAlchemy 的起源
      • 2. SQLAlchemy 的核心组件
        • 2.1 核心 SQL 工具包
        • 2.2 ORM 层
      • 3. SQLAlchemy 的优势
        • 3.1 灵活性
        • 3.2 跨数据库支持
        • 3.3 强大的社区支持
    • 二.实战步骤
      • 1.数据库配置
      • 2.model
      • 3.连接配置
      • 4.调用 SQL

一.基础介绍

SQLAlchemy 是一个 Python 的 SQL 工具包和对象关系映射(ORM)工具,它提供了一个高层的 ORM 以及底层的 SQL 表达式语言。SQLAlchemy 是开源的,并且可以在商业和非商业项目中免费使用。它支持多种数据库系统,包括 PostgreSQL、MySQL、SQLite 等。
在这里插入图片描述

1. SQLAlchemy 的起源

SQLAlchemy 最初由 Michael Bayer 在 2005 年创建,目的是提供一个全面的 SQL 工具包和 ORM 解决方案,以满足 Python 社区的需求。随着时间的推移,SQLAlchemy 不断发展和完善,成为了 Python 数据库编程领域中最受欢迎的库之一。

2. SQLAlchemy 的核心组件

2.1 核心 SQL 工具包

SQLAlchemy 的核心 SQL 工具包提供了构建 SQL 查询的功能,它允许开发者以 Pythonic 的方式编写 SQL 语句。这包括了对数据库表的创建、数据的增删改查等操作。

2.2 ORM 层

ORM(Object-Relational Mapping)层是 SQLAlchemy 的另一个重要组成部分,它允许开发者使用 Python 类和对象来表示数据库中的表和行。ORM 层抽象了数据库操作,使得开发者可以不必编写 SQL 语句,而是通过操作 Python 对象来间接地与数据库交互。

3. SQLAlchemy 的优势

3.1 灵活性

SQLAlchemy 提供了灵活的 SQL 构建工具,开发者可以自由地编写 SQL 语句,同时也可以利用 ORM 层提供的抽象来简化数据库操作。

3.2 跨数据库支持

SQLAlchemy 支持多种数据库系统,这意味着开发者可以使用相同的代码库来操作不同的数据库,而不需要为每种数据库编写特定的代码。

3.3 强大的社区支持

由于 SQLAlchemy 的流行,它拥有一个活跃的社区,开发者可以在社区中找到大量的资源和帮助,包括文档、教程和第三方库。

二.实战步骤

1.数据库配置

# 数据库
database:
  TYPE: mysql
  DATABASE_URL: mysql://root:xxx@xxxx:9306/test?serverTimezone=Asia/Shanghai
  USERNAME: root
  PASSWORD: xxx
  HOST: xxxx
  PORT: 9306
  DBNAME: test
  MAX_OVERFLOW: 60
  POOL_TIMEOUT: 120
  POOL_SIZE: 30
  URL_PROPERTY: ?charset=utf8
  ECHO: True

2.model

from datetime import datetime

import pytz
from sqlalchemy import String, Column, Text, DateTime, JSON
from sqlalchemy.ext.asyncio import AsyncAttrs
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, attributes


def get_beijing_now():
    # 获取当前系统时区
    return datetime.now(pytz.timezone('Asia/Shanghai'))


# 基类
class Base(AsyncAttrs, DeclarativeBase):
    id: Mapped[int] = mapped_column(primary_key=True)
    create_time = Column(DateTime, default=get_beijing_now, nullable=False)
    update_time = Column(DateTime, default=get_beijing_now, onupdate=get_beijing_now, nullable=False)

    def to_dict(self):
        """
        转为字典输出
        :return:
        """
        return {c.name: getattr(self, c.name) for c in self.__table__.columns}


@repr_generator
class AlchemyEntitySchemas(Base):
    __tablename__ = "entity_schemas"

    name = Column(String(255), nullable=False, comment='名称')

3.连接配置

from sqlalchemy.pool import QueuePool
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.sql import text
from base.config import get_config_key
from urllib.parse import quote_plus as urlquote
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, AsyncEngine, async_sessionmaker


class Database:

    def __init__(self, url, pool_size=30, pool_timeout=1200, max_overflow=60, echo=False):
        try:
            self.engine = create_engine(url, poolclass=QueuePool, pool_size=pool_size,
                                        max_overflow=max_overflow, pool_timeout=pool_timeout,
                                        echo=echo, pool_recycle=7200, pool_pre_ping=True, echo_pool=echo)
            self.Session = sessionmaker(bind=self.engine, expire_on_commit=False, autocommit=False, autoflush=False)
            print("Database connected successfully.")
        except SQLAlchemyError as e:
            print(f"Error connecting to the database: {e}")

    def get_session(self):
        return self.Session()

    @staticmethod
    def close_session(_session):
        _session.close()

    @staticmethod
    def execute_query(query, _session):
        try:
            result = _session.execute(query)
            return result.fetchall()
        except SQLAlchemyError as e:
            print(f"Error executing query: {e}")
            return None
        finally:
            Database.close_session(_session)


class SyncDatabase:
    async_engine: AsyncEngine = None
    async_session = None

    def __init__(self, url, pool_size=30, pool_timeout=1200, max_overflow=60, echo=False):
        self.url = url
        self.max_overflow = max_overflow
        self.pool_timeout = pool_timeout
        self.pool_size = pool_size
        self.echo = echo
        self.connect()

    def connect(self):
        """创建数据库引擎和会话类"""
        try:
            self.async_engine = create_async_engine(self.url, echo=self.echo, pool_size=pool_size,
                                                    max_overflow=max_overflow, pool_timeout=pool_timeout,
                                                    pool_recycle=7200,
                                                    pool_pre_ping=True, echo_pool=self.echo)
            self.async_session = async_sessionmaker(bind=self.async_engine, class_=AsyncSession, expire_on_commit=False,
                                                    autocommit=False, autoflush=False)
            print("Database connected successfully.")
        except SQLAlchemyError as e:
            print(f"Error connecting to the database: {e}")


def get_db_url():
    userName = get_config_key("database", "USERNAME")
    password = get_config_key("database", "PASSWORD")
    dbHost = get_config_key("database", "HOST")
    dbPort = get_config_key("database", "PORT")
    dbName = get_config_key("database", "DBNAME")
    urlProperty = get_config_key("database", "URL_PROPERTY")

    if dbName is None:
        return f'mysql+pymysql://{userName}:{urlquote(password)}@{dbHost}:{dbPort}{urlProperty}'
    else:
        return f'mysql+pymysql://{userName}:{urlquote(password)}@{dbHost}:{dbPort}/{dbName}{urlProperty}'


def get_sync_db_url():
    userName = get_config_key("database", "USERNAME")
    password = get_config_key("database", "PASSWORD")
    dbHost = get_config_key("database", "HOST")
    dbPort = get_config_key("database", "PORT")
    dbName = get_config_key("database", "DBNAME")
    urlProperty = get_config_key("database", "URL_PROPERTY")
    if dbName is None:
        return f'mysql+aiomysql://{userName}:{urlquote(password)}@{dbHost}:{dbPort}{urlProperty}'
    else:
        return f'mysql+aiomysql://{userName}:{urlquote(password)}@{dbHost}:{dbPort}/{dbName}{urlProperty}'


url = get_db_url()
max_overflow = get_config_key("database", "MAX_OVERFLOW")
pool_timeout = get_config_key("database", "POOL_TIMEOUT")
pool_size = get_config_key("database", "POOL_SIZE")
echo = get_config_key("database", "ECHO")

# sqlalchemy实际操作对象,导入的时候应该导入这个对象
get_sqlalchemy_db = Database(url, pool_size=pool_size, pool_timeout=pool_timeout, max_overflow=max_overflow, echo=echo)

# 异步的
SYNC_DB_URI = get_sync_db_url()
_async_engine = create_async_engine(SYNC_DB_URI, echo=echo, pool_size=pool_size,
                                    max_overflow=max_overflow, pool_timeout=pool_timeout, pool_recycle=7200,
                                    pool_pre_ping=True, echo_pool=echo)
# 异步IO的 sqlalchemy实际操作对象,导入的时候应该导入这个对象
async_session_factory = async_sessionmaker(bind=_async_engine, class_=AsyncSession, expire_on_commit=False,
                                           autocommit=False, autoflush=False)

在这里插入图片描述

4.调用 SQL

@staticmethod
async def find_by_name(name: str):
    """
    根据名称查询
    """
    db = get_sqlalchemy_db
    try:
        with Session(db.engine) as session:
            stmt = select(AlchemySchemas)
            if name:
                stmt = stmt.where(AlchemySchemas.name == name)
            schemas_infos = session.scalars(stmt).all()
            return [schemas_info.to_dict() for schemas_info in schemas_infos] if schemas_infos else None
    except SQLAlchemyError as e:
        print(f"An error occurred: {e}")
        return None
    finally:
        db.close_session(session)

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2091857.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详说 类和对象

类怎么定义 类是什么呢?类就是我们上篇文说的命名空间,单独创建一个域,自己有自己的生命空间,那么类怎么定义呢?C规定,假设 stack就是他的类名,那么前面要加个class,换行之后就是他…

软件测试面试八股文(含答案解析+文档)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、软件测试基础面试题 1、阐述软件生命周期都有哪些阶段? 常见的软件生命周期模型有哪些? 软件生命周期是指一个计算机软件从功能确定设计,到…

如何在D盘创建虚拟环境?包括安装PyTorch和配置PyCharm

摘要:本文首先在D盘创建了虚拟环境,然后在虚拟环境中安装了PyTorch,最后配置了pycharm的解释器。 1. 在 D 盘创建虚拟环境 打开Anaconda Prompt 输入conda info --envs查看当前已有环境 创建自己的虚拟环境,打算命名为py310&…

一文彻底搞懂大模型 - GPT和LlaMA的模型架构

GPT vs LlaMA GPT与LlaMA,作为大语言模型的两大巨擘,均基于Transformer架构却各有千秋。GPT系列以强大的生成能力著称,通过不断增大的参数规模引领复杂语言与推理任务的前沿;而Llama则以开源姿态,通过技术创新提升模型…

江协科技stm32————10-5 硬件I2C读写MPU6050

步骤 一、配置I2C外设,对I2C2外设进行初始化(MyI2C_Init) 开启I2C外设和对应的GPIO口的时钟把I2C对应的GPIO口初始化为复用开漏模式使用结构体配置I2CI2C_Cmd,使能I2C I2C_GenerateSTART //生产起始条件 I2C_GenerateSTOP /…

MySQL:复合查询

MySQL:复合查询 聚合统计分组聚合统计group byhaving 多表查询自连接子查询单行子查询多行子查询多列子查询from子查询 合并查询unionunion all 内连接外连接左外连接右外连接全外连接 视图 MySQL 复合查询是数据分析和统计的强大工具,本博客将介绍如何使…

黑马点评——商户查询缓存(P37店铺类型查询业务添加缓存练习题答案)redis缓存、更新、穿透、雪崩、击穿、工具封装

文章目录 什么是缓存?添加Redis缓存店铺类型查询业务添加缓存练习题 缓存更新策略给查询商铺的缓存添加超时剔除和主动更新的策略 缓存穿透缓存空对象布隆过滤 缓存雪崩解决方案 缓存击穿解决方案基于互斥锁方式解决缓存击穿问题基于逻辑过期的方式解决缓存击穿问题…

【教程】实测np.fromiter 和 np.array 的性能

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 目录 函数简介 np.fromiter np.array 测试代码 实验结果 结果分析 实验总结 学长想说 函数简介 np.fromiter np.fromiter 是 NumPy 提供的一…

【SuperCraft AI:无限工作流画布】

SuperCraft AI:无限工作流画布 SuperCraft 是一款全新的 AI 工具。它具有将手绘草图转换为不同产品图像的功能,提供了一个无限大的协作画布,让设计师能够在此手绘草图,并利用生成式 AI 技术将草图转化为高质量的 2D 图像和 3D 渲…

NC 二分查找-II

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 描述 请实现有重复…

Unity TreeView扩展

实现效果 这里原来是做的一个检测网络、事件回调耗时的工具。简单改了成了一个演示TreeView的demo。实现了TreeView的基本功能并且实现了对列的排序。TreeView还可以制作点击,双击,右键等事件,但这里暂时不需要用到。 思维导图 工程&#xf…

arcgisjs4.0 内网部署字体不显示问题处理

问题背景问题定位解决方案 问题背景 内网环境,通过压缩包的hash值验证了包是一摸一样的,ningx也读到了index.html,但是网格的字提显示出不来,并且地图上的注记文字均不显示 本地环境地图情况: 内网环境地图情况&…

Bluetooth: att protocol

一篇搞懂 ATT 支持的东西都有什么。 READ_BY_GROUP_TYPE_REQ/RSP 如下是 Spec 内容: The attributes returned shall be the attributes with the lowest handles within the handle range. These are known as the requested attributes.If the attributes with the requeste…

石油设备和相关机械都包涵那些?

关键字:钻杆测径仪,泵管测径仪,固井管道直线度测量仪,输送管测径仪,输送管检测设备, 石油设备是指在石油和天然气的勘探、开发、生产、储存和运输等过程中使用的各种机械和装置。这些设备通常包括但不限于…

黄力医生科普:如何有效预防冠心病,这几个保健措施不可少!

冠心病,作为心血管系统的一种常见病,主要因冠状动脉粥样硬化导致管腔狭窄或闭塞,进而引发心肌缺血缺氧。此病多发于中老年群体,且具有一定遗传性。然而,无论发病因素如何,我们都可以通过一系列有效的预防措…

C++类和对象(6)——初始化列表

一般的初始化 class A { public:A(int a){ //一般的初始化&#xff0c;在{}括号里面给成员变量赋值_a a;cout << _a << endl;}~A() {}private:int _a; }; 用 初始化列表 初始化 当成员变量是以下两种情况时&#xff0c; 必须使用初始化列表&#xff01; cons…

单自由度无阻尼系统振动分析

特别感谢&#xff1a;https://www.bilibili.com/video/BV114411y7ab/?p6&spm_id_frompageDriver&vd_sourceebe07816bf845358030fc92d23830b29 本文图片该系列视频 tips&#xff1a;关于特征方程与振动方程&#xff1a; 特征方程有助于我们理解和确定系统的固有频率和模…

【算法】贪心算法解析:基本概念、策略证明与代码例题演示

文章目录 1. 什么是贪心算法&#xff1f;2. 贪心算法的特点3. 例题&#xff08;贪心策略&#xff09;① 找零问题② 最小路径和③ 背包问题 4. 贪心策略证明 1. 什么是贪心算法&#xff1f; 在学习贪心算法之前&#xff0c;一定要理解的是贪心策略&#xff1a; 贪心策略是一种…

Ubuntu中qt类与类信号槽的创建及使用

今天学习到了新的一个小玩意&#xff0c;我们在QT中创建一个大项目的时候一般会创建多个类&#xff0c;那我们就来学习一下如何在自定义的类中声名和使用信号与槽函数。 首先我们CTRLn来创建我们新的类&#xff1a; 我们创建新的C的类&#xff0c;一个School&#xff0c;一个S…

举办知识竞赛是线上好还是线下好

举办知识竞赛线上和线下各有优势&#xff0c;选择哪种方式取决于具体的需求和条件。 线上举办知识竞赛的优缺点&#xff1a; 优点&#xff1a; 便捷性&#xff1a;线上竞赛不受地域限制&#xff0c;参与者可以在任何有网络的地方参与。 选手数&#xff1a;可以同时满足人数较…