异步SQLAlchemy

SQLAlchemy作为一款通用的Python Orm工具,在最近的版本也支持了异步操作。但网上很多资料都不是很齐全,API也不是很好查询的情况下,我便有了整理一份基础文档的想法。文章主要会以CRUD为入口,解决大家最基本的需求。

engine的区别

在普通的SQLAlchemy中,建立engine对象,我们会采用下面的方式:

  1. from sqlalchemy import create_engine
  2. engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_recycle=1500)

而异步的方式如下:

  1. from sqlalchemy.ext.asyncio import create_async_engine
  2. async_engine = create_async_engine(ASYNC_SQLALCHEMY_URI, pool_recycle=1500)

session的区别

我们一般用sessionmaker来建立session,不过异步的有点区别:

  1. from sqlalchemy.ext.asyncio import AsyncSession
  2. from sqlalchemy.orm import sessionmaker
  3. # 同步session
  4. Session = sessionmaker(engine)
  5. # 异步session 区别在于需要指定对应的class_
  6. async_session = sessionmaker(async_engine, class_=AsyncSession)

建立会话

我们还是以代码的形式展示:

  1. # 同步
  2. with Session() as session:
  3. # 里面是具体的sql操作
  4. pass
  5. # 异步
  6. async with Session() as session:
  7. # 里面是异步的操作,区别就是从with变成了async with 也就意味着方法必须是async修饰的
  8. pass

以上是关于建立连接,处理会话的一些区别,接着我们讲对应的CRUD操作。

查询

这里依旧会给出新老版本的对比:

  1. # 注意Session为同步Session,为了区分,异步session为async_session
  2. # model则为具体的Model类
  3. # 异步查询方式
  4. from sqlalchemy import select
  5. async def query():
  6. async with async_session() as session:
  7. sql = select(model).where(model.id == 1)
  8. print(sql) # 这里可以打印出sql
  9. result = await session.execute(sql)
  10. # 第一条数据
  11. data = result.scalars().first()
  12. # 所有数据
  13. # data = result.scalars().all()
  14. # 同步查询方式一
  15. def query():
  16. with Session() as session:
  17. # 查询id=1的第一条数据 result对应的就是model的实例 如果没有则是None
  18. result = session.query(model).filter_by(id=1).first()
  19. # 查询所有数据 result对应的数据为List[model],即model数组
  20. # result = session.query(model).filter_by(name="zhangsan").all()
  21. # 同步查询方式二
  22. def query():
  23. with Session() as session:
  24. # 查询id=1的第一条数据 result对应的就是model的实例 如果没有则是None
  25. result = session.query(model).filter(model.id == 1).first()
  26. # 查询所有数据 result对应的数据为List[model],即model数组
  27. # result = session.query(model).filter(model.name == "zhangsan").all()

新增

这里开始就只讲异步的操作了。

  1. async def insert(data):
  2. async with async_session() as session:
  3. async with session.begin():
  4. session.add(data)
  5. # 刷新自带的主键
  6. await session.flush()
  7. # 释放这个data数据
  8. session.expunge(data)
  9. return data

先说一下session.begin,这个你可以理解为一个事务操作,当采用session的begin方法后,你可以发现我们不需要调用commit方法也能把修改存入数据库。

expunge方法,是用例释放这个实例,SQLAlchemy有个特点,当你的session会话结束以后,它会销毁你插入的这种临时数据,你再想访问这个data就访问不了了。所以我们可以释放这个数据。(expunge的作用)

编辑

一般编辑有2种方式:

  • 查询出对应的数据,在数据上修改
  • 根据key-value的形式,修改对应数据的字段
  1. from sqlalchemy import select, update
  2. # 方式一
  3. async def update_record(model):
  4. async with async_session() as session:
  5. async with session.begin():
  6. result = await session.execute(select(model).where(id=1))
  7. now = result.scalars().first()
  8. if now is None:
  9. raise Exception("记录不存在")
  10. now.name = "李四"
  11. now.age = 23
  12. # 这里测试过,如果去掉flush会导致数据不更新
  13. await session.flush()
  14. session.expunge(now)
  15. return now
  16. # 方式二
  17. async def update_by_map():
  18. async with async_session() as session:
  19. async with session.begin():
  20. # 更新id为1的数据,并把name改为李四 age改为23
  21. sql = update(model).where(model.id == 1).values(name="李四", age=23)
  22. await session.execute(sql)

删除

删除的话,软删除大家都是update,所以不需要多说,物理删除的话,也有两种方式:

  • 查到以后删除之
  • 直接根据条件删除(这种我没有仔细研究,我选的是第一种方式,容错率高点)
  1. async def delete_by_id():
  2. async with async_session() as session:
  3. async with session.begin():
  4. result = await session.execute(select(model).where(model.id == 2))
  5. original = result.scalars().first()
  6. if original is None:
  7. raise Exception("记录不存在")
  8. # 如果是多条
  9. # session.delete(original)
  10. # for item in result:
  11. # session.delete(item)

今天的异步内容就整理到这里,我个人觉得还是很实用的,希望对大家有帮助~~~

Sqlalchemy异步操作不完全指北的更多相关文章

  1. 后端API入门到放弃指北

    后端API入门学习指北 了解一下一下概念. RESTful API标准] 所有的API都遵循[RESTful API标准]. 建议大家都简单了解一下HTTP协议和RESTful API相关资料. 阮一 ...

  2. c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)

    c#封装DBHelper类   public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...

  3. git宝典—应付日常工作使用足够的指北手册

    最近公司gitlab又迁移,一堆git的命令骚操作,然鹅git命令,感觉还是得复习下——其实,git现在界面操作工具蛮多,比如intellij 自带的git操作插件就不错,gitlab github ...

  4. Python 简单入门指北(二)

    Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值.总而言之,函数和普通变量 ...

  5. Python 简单入门指北(一)

    Python 简单入门指北(一) Python 是一门非常容易上手的语言,通过查阅资料和教程,也许一晚上就能写出一个简单的爬虫.但 Python 也是一门很难精通的语言,因为简洁的语法背后隐藏了许多黑 ...

  6. 可能比文档还详细--VueRouter完全指北

    可能比文档还详细--VueRouter完全指北 前言 关于标题,应该算不上是标题党,因为内容真的很多很长很全面.主要是在官网的基础上又详细总结,举例了很多东西.确保所有新人都能理解!所以实际上很多东西 ...

  7. 关于supervisor的入门指北

    关于supervisor的入门指北 在目前这个时间点(2017/07/25),supervisor还是仅支持python2,所以我们要用版本管理pyenv来隔离环境. pyenv 根据官方文档的讲解, ...

  8. 关于Gevent的使用指北

    关于Gevent的使用指北 只是看了入门指南,和一个翻译文档.写一下个人读书心得. 其实看完之后,第一个反映就是asyncio这个系统库,感觉gevent现在所做的一些事情是与asyncio很像的,但 ...

  9. Celery入门指北

    Celery入门指北 其实本文就是我看完Celery的官方文档指南的读书笔记.然后由于我的懒,只看完了那些入门指南,原文地址:First Steps with Celery,Next Steps,Us ...

随机推荐

  1. mysql优化参数 (汇总)

    1 如下为128G内存32线程处理器的mariadb配置参数优化: [client]#password= your_passwordport= 3306 socket= /tmp/mysql.sock ...

  2. OpenMLDB 在线模块架构解析

    本文介绍 OpenMLDB 在线模块的架构,欢迎通过以下渠道了解关于 OpenMLDB 的更多信息 GitHub:GitHub - 4paradigm/OpenMLDB: OpenMLDB is an ...

  3. 记-Golang获取本机IP及快速搭建局域FTP

    1 package main 2 3 import ( 4 "fmt" 5 "net" 6 "net/http" 7 "strin ...

  4. synchronized底层实现原理及锁优化

    一.概述 1.synchronized作用 原子性:synchronized保证语句块内操作是原子的 可见性:synchronized保证可见性(通过"在执行unlock之前,必须先把此变量 ...

  5. docker-compose安装和使用

    安装:https://my.oschina.net/thinwonton/blog/2985886 docker-compose和Dockerfile结合使用,创建django项目和postgres数 ...

  6. memcached 的内存分配器是如何工作的?为什么不适用 malloc/free!?为何要使用 slabs?

    实际上,这是一个编译时选项.默认会使用内部的 slab 分配器.您确实确实应该 使用内建的 slab 分配器.最早的时候,memcached 只使用 malloc/free 来管理 内存.然而,这种方 ...

  7. SpringBoot 自定义配置文件不会自动提示问题

    参阅:https://www.jianshu.com/p/ec3f0b0371e6

  8. Linux如何查看某个端口是否被占用

    1.netstat  -anp  |grep   端口号 2.netstat   -nultp(此处不用加端口号) 3.netstat  -anp  |grep  82    查看82端口的使用情况

  9. 调用高德地图web api 规划路线

    实现地图输出,出发地与目的地路线,效果如下 具体代码如下 <!doctype html> <html> <head> <meta charset=" ...

  10. 攻防世界杂项MISCall

    MISCall 下载下来是一个附件但是不清楚他是个什么东西我先拉入kali看看 发现是一个tar包不过这个包我们需要使用以下的指令来解压 tar -xjvf d02f31b893164d56b7a8e ...