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())
相关推荐
要开心吖ZSH1 小时前
Java事务与MySQL事务的关系及MVCC通俗解析
java·开发语言·mysql·mvcc
火星校尉1 小时前
一场数据基建与消费场景的跨界实验
java·前端·数据库·python·php
平安的平安1 小时前
从“云端排队“到“边缘上岗“:DolphinDB 云边协同如何重塑工业现场的实时智能
数据库
Sam09271 小时前
【AI 算法精讲 14】TF-IDF:词频与逆文档频率
人工智能·python·算法·ai
懒鸟一枚2 小时前
为什么 useradd -rs /bin/false service 创建的用户无法用 su 切换?
linux·服务器·数据库
爱喝热水的呀哈喽2 小时前
hypermesh两个网格参数解析
服务器·数据库·mysql
万亿少女的梦1682 小时前
基于Spring Boot的楚雄旅游景区门票售卖系统设计与实现
java·spring boot·mysql·vue·系统设计
内蒙深海大鲨鱼2 小时前
数据操作+数据预处理
python
ai生成式引擎优化技术2 小时前
从参数驱动到认知行为驱动:SAI范式的理论转向与WSaiOS认知内核架构
python·架构·django·virtualenv·pygame
想你依然心痛2 小时前
AtomCode在Python数据科学项目中的使用体验:从数据分析到可视化
开发语言·python·数据分析