Python SqlAlchemy对数据库各种操作整理(MySQL为例)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

这段时间研究都在学习python,所以对Python SqlAlchemy对数据库各种操作整理(MySQL为例),大家相互学习,也当是作为笔记,以后copy来用。


一、装包

SqlAlchemy: pip install "sqlalchemyasyncio" aiomysql

db frist方式依赖包: pip install pymysql sqlacodegen

二、数据库直接生成模型类脚本文件(RefeshModels.bat)

bat 复制代码
@echo off
chcp 65001 >nul
echo 正在强制刷新数据库模型(先删后建)...

if exist "models.py" del /f /q "models.py"

sqlacodegen mysql+pymysql://root:xxx@localhost/db_py_orm_test --outfile models.py

if %errorlevel% equ 0 (
    echo 模型已强制覆盖更新!
) else (
    echo 生成失败,请检查数据库连接或参数。
)
pause

1、这个脚本文件里面"models.py"这个就是模型类的文件路径了,我这里是根目录,你可以根据自己需要去改到其他目录;

2、数据库名字等连接字符串信息根据自己情况改一下就行

3、每次数据库更新了运行一下这个脚本就行

二、我的模型类,也就是那个models.py

python 复制代码
from typing import Optional
import datetime

from sqlalchemy import DateTime, Float, String
from sqlalchemy.dialects.mysql import INTEGER
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

class Base(DeclarativeBase):
    pass


class Author(Base):
    __tablename__ = 'author'

    Id: Mapped[str] = mapped_column(String(50), primary_key=True)
    Name: Mapped[Optional[str]] = mapped_column(String(20))
    Age: Mapped[Optional[int]] = mapped_column(INTEGER(11))


class Book(Base):
    __tablename__ = 'book'

    Id: Mapped[str] = mapped_column(String(50), primary_key=True, comment='ID')
    CreateDatetime: Mapped[datetime.datetime] = mapped_column(DateTime, nullable=False, comment='CreateDate')
    Title: Mapped[Optional[str]] = mapped_column(String(50), comment='Title')
    Author_: Mapped[Optional[str]] = mapped_column('Author', String(20), comment='Author')
    Price: Mapped[Optional[float]] = mapped_column(Float, comment='Price')

三、DbConfig.py

python 复制代码
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession

connectionString="mysql+aiomysql://root:xxx@localhost:3306/db_py_orm_test?charset=utf8"
asyncEngine = create_async_engine(
    connectionString,
    echo=False,
    pool_size=10,
    max_overflow=20
)
AsyncSessionLocal=async_sessionmaker(
    bind=asyncEngine,
    class_=AsyncSession,
    expire_on_commit=False
)

async def getDatabase():
    async with AsyncSessionLocal() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()

四、main.py(重点,示例代码在这里面)

这里需要注意的是那个异步引擎一定要Dispose

python 复制代码
import uuid

from sqlalchemy import text, select, update, delete, join, insert, exists
import asyncio

from sqlalchemy.sql.operators import and_, or_
from sqlalchemy.testing import in_

from DbConfig import AsyncSessionLocal, asyncEngine
from models import Book, Author
from datetime import datetime

"""
获取所有书籍信息 返回值是元组列表
"""


async def getBooks():
    async with AsyncSessionLocal() as session:
        return (await session.execute(text("SELECT * FROM book;"))).all()


"""
获取第一条:有就返回第一条,没有就是none,
返回的是元组|None
"""


async def getBookFirst():
    async with AsyncSessionLocal() as session:
        return (await session.execute(text("SELECT \
	* \
FROM \
	book \
WHERE \
	Price > 200 \
ORDER BY \
	CreateDatetime DESC;"))).first()


"""
返回一条或没有,
当存在多条结果抛出异常
"""


async def getBookByTitle(title):
    async with AsyncSessionLocal() as session:
        return (await session.execute(text("SELECT \
	* \
FROM \
	book \
WHERE \
	Title = :title;"), {"title": title})).one_or_none()


"""
单一条件的筛选
"""


async def getBooksV2():
    async with AsyncSessionLocal() as session:
        return (await session.execute(select(Book).where(Book.Price > 50))).scalars().all()


"""
复杂条件筛选
"""


async def getBooksV3():
    async with (AsyncSessionLocal() as session):
        return (await session.execute(select(Book)
        .where(
            or_(
                and_(Book.Price > 50, Book.Author.like("吴%")),
                Book.Title == "红楼梦"
            )
        )
        )).scalars().all()


"""
更新操作V1
"""


async def updatePrice():
    async with AsyncSessionLocal() as session:
        queryResult = await session.execute(update(Book)
                                            .where(Book.Id == "981dcd3b-cbcc-4663-823b-87bebf76bfbe")
                                            .values(Price=80))
        await session.commit()
        return queryResult.rowcount > 0


"""
更新操作V2
"""


async def updatePriceV2():
    async with AsyncSessionLocal() as session:
        book = (await session.execute(select(Book).where(Book.Id == "981dcd3b-cbcc-4663-823b-87bebf76bfbe"))) \
            .scalars() \
            .one_or_none()
        if not book:
            return "书籍信息不存在"
        book.Price = 80
        await session.commit()
        return "OK"


"""
删除V1
"""


async def deleteBook():
    async with AsyncSessionLocal() as session:
        queryResult = await session.execute(delete(Book)
                                            .where(Book.Id == "981dcd3b-cbcc-4663-823b-87bebf76bfbe"))
        await session.commit()
        return queryResult.rowcount > 0


"""
删除V2
"""


async def deleteBookV2():
    async with AsyncSessionLocal() as session:
        book = (await session.execute(select(Book)
                                      .where(Book.Id == "ea1b2895-2210-4666-a4b5-fb68a8ff1c19"))) \
            .scalars() \
            .one_or_none()
        if not book:
            return "书籍信息不存在"
        await session.delete(book)
        await session.commit()
        return "OK"


"""
联表查询
"""


async def getBooksV4():
    async with AsyncSessionLocal() as session:
        return (await session.execute(
            select(join(Book, Author, Book.Author_ == Author.Name))
            .where(Book.Price > 50)
        )).all()


"""
联表查询(只要部分字段)
"""


async def getBooksV5():
    async with AsyncSessionLocal() as session:
        return (await session.execute(
            select(Book.Title, Author.Name, Author.Age)
            .select_from(join(Book, Author, Book.Author_ == Author.Name))
        )).all()


"""
批量新增书籍
"""


async def batchInsertBooks(books):
    async with AsyncSessionLocal() as session:
        for book in books:
            if not (await session.execute(select(exists().where(Author.Name == book["Author"])))).scalar():
                return "作者信息不存在"
            if (await session.execute(select(exists().where(Book.Title == book["Title"])))).scalar():
                return "书籍信息已存在"

        queryResult = await session.execute(insert(Book).values(books))
        await session.commit()
        if queryResult.rowcount > 0:
            return "OK"
        else:
            return "新增失败"

"""
批量删除书籍
"""
async def batchDeleteBooks(ids):
    async with AsyncSessionLocal() as session:
        queryResult=await session.execute(delete(Book).where(Book.Id.in_(ids)))
        await session.commit()
        return queryResult.rowcount >0



async def main():
    print("=====================================================================")

    # books = await getBooks()
    # for book in books:
    #     print(book)

    # book=await getBookFirst()
    # if book:
    #     print(book)
    # else:
    #     print("Book not found")

    # book=await getBookByTitle("西游记")
    # if book :
    #     print(book)
    # else:
    #     print("Book not found")

    # books = await getBooksV3()
    # for book in books:
    #     print(f"{book.Id} {book.Title} {book.Author} {book.Price} {book.CreateDatetime}")

    # if await updatePrice():
    #     print("更新成功")
    # else:
    #     print("更新失败")

    # if (await updatePriceV2())!="OK":
    #     print("更新失败")
    # else:
    #     print("更新成功")

    # if await deleteBook():
    #     print("删除成功")
    # else:
    #     print("删除失败")

    # if (await deleteBookV2())!="OK":
    #     print("删除失败")
    # else:
    #     print("删除成功")

    # books = await getBooksV5()
    # for book in books:
    #     print(book)

    # result = await batchInsertBooks([
    #     {
    #         "Id": str(uuid.uuid4()),
    #         "Title": "红楼梦",
    #         "Author": "曹雪芹",
    #         "Price": 60,
    #         "CreateDatetime": datetime.now()
    #     }, {
    #         "Id": str(uuid.uuid4()),
    #         "Title": "西游记",
    #         "Author": "吴承恩",
    #         "Price": 80,
    #         "CreateDatetime": datetime.now()
    #     }])
    # if result=="OK":
    #     print("新增成功")
    # else:
    #     print(result)

    if await batchDeleteBooks(["57e2cd30-537f-429b-bb35-d270264d48cd","7805a7af-5a96-4d33-b1a3-9ac9ef48d2a9"]):
        print("删除成功")
    else:
        print("删除失败")

    print("=====================================================================")
    await asyncEngine.dispose()
    print("OK")


if __name__ == "__main__":
    asyncio.run(main())
相关推荐
tkevinjd3 小时前
MiniCode 项目详解6:原项目控制系统的10个缺陷(已修复)
python·llm·agent
聆听。。花开雨落4 小时前
mybatis的typeHandler 作用
数据库·mybatis
dNGUZ7UGj4 小时前
10分钟完成第一个Python小游戏
python·django
pxzsky4 小时前
PG17数据库安装中分分词插件:pg_jieba
数据库·postgresql·pg_jieba
没有梦想的咸鱼185-1037-16634 小时前
AI-Python机器学习与深度学习技术:CNN/Transformer/扩散模型、SHAP可解释及Hermes智能体自动化
人工智能·python·深度学习·机器学习·chatgpt·cnn·transformer
霸道流氓气质5 小时前
SpringBoot中通用工具类库(Utils)封装与使用实践
spring boot·后端·python
她说可以呀5 小时前
Redis哨兵
数据库·redis·bootstrap
霸道流氓气质5 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
kirs_ur5 小时前
CXL(Compute Express Link)— 内存扩展的未来
服务器·数据库·性能优化