当前位置:   article > 正文

Python ORM 框架 SQLAlchemy 的简单使用_python orm工具

python orm工具

目录

 

一·SQLAlchemy介绍

二·概念与数据类型预习

 三·使用步骤

1.安装依赖包

2.创建连接

3.创建实体对象

4.创建数据表

 5.数据操作

四·工具方法封装

增删改查代码封装

实体类修改构造方法

工具的使用:


一·SQLAlchemy介绍

SQLAlchemy 是 Python SQL工具集和对象关系映射框架(ORM),为开发者提供了强大且灵活的数据库操作。

他提供了一整套著名的企业级持久化存储模式,具有高效、高性能的数据库访问设计,并适配于简单易用的 Python 语言。

上述描述来自SQLAlchemy官方网站,更多详情请查看链接

二·概念与数据类型预习

SQLAlchemy相关概念说明
SQLAlchemy概念对应数据库的概念说明
Engine数据库连接客户端连接数据库,需确认地址、用户等参数
Session数据库会话数据库CRUD交互会话
ModelModel是ORM中的类定义,对应数据库中的表格
ColumnColumn是对象在定义时,用于指定数据表的列属性
Query查询表示一次查询

 

常用数据类型比较
SQLAlchemy 数据类型数据库数据类型Python数据类型备注
Integerintint 
StringStringstr 
Texttextstr 
Floatfloatfloat 
Booleantinyintbool 
Datedatedatetime.date 
DateTimedatetimedatetime,datetime 
Timetimedatetime.datetime 

 三·使用步骤

1.安装依赖包

  1. # 安装mysql数据库Python依赖包
  2. pip install pymysql
  3. # 安装ORM框架
  4. pip install SQLAlchemy

2.创建连接

这里假设使用的是本地的MySQL数据库,数据库名 test, 数据表名 STUDENTS。

  1. from sqlalchemy import create_engine
  2. # 数据使用本地,用户名root, 密码123456,数据库名test,密码123456(我随便取的,开发时一定注意密码的复杂度问题)
  3. db_link = f'mysql+pymysql://root:123456@127.0.0.1:3306/test'
  4. # 获取数据库连接对象
  5. engine = create_engine(db_link)
  6. engine = create_engine(db_link,
  7. echo=True,
  8. pool_size=8,
  9. pool_recycle=60*30
  10. )
  11. # echo: 当设置为True时会将orm语句转化为sql语句打印,一般debug的时候可用
  12. # pool_size: 连接池的大小,默认为5个,设置为0时表示连接无限制
  13. # pool_recycle: 设置时间以限制数据库多久没连接自动断开

3.创建实体对象

ORM的重要特点,就是我们操作表的时候就需要通过操作对象来实现,现在我们来创建一个类,以常见的学生表举例:

  1. from sqlalchemy import Column, String, Integer
  2. from sqlalchemy.ext.declarative import declarative_base
  3. # 创建对象的基类:
  4. Base = declarative_base()
  5. # 定义User对象:
  6. class Student(Base):
  7. # 表的名字:
  8. __tablename__ = 'STUDENTS'
  9. def __init__(self, name, age, gender):
  10. self.name = name
  11. self.age = age
  12. self.gender = gender
  13. # 表的结构:
  14. id = Column(name='stu_id', type_=Integer, primary_key=True, autoincrement=True)
  15. name = Column(name='stu_name', type_=String(20))
  16. age = Column(name='stu_age', type_=Integer)
  17. gender = Column(name='stu_gender', type_=String(20))

declarative_base()是sqlalchemy内部封装的一个方法,通过其构造一个基类,这个基类和它的子类,可以将Python类和数据库表关联映射起来。

数据库表模型类通过__tablename__和表关联起来,Column表示数据表的列。

4.创建数据表

如数据表已通过执行SQL语句创建,则忽略此步骤

  1. # 创建数据表
  2. Base.metadata.create_all(engine)

执行结果如图所示

 

 5.数据操作

获取session会话

sqlalchemy中使用session对象用于创建程序和数据库之间的会话,所有对象的载入和保存都需要通过session对象 。

通过sessionmaker调用创建一个session工厂,并关联Engine,以确保每个session都可以使用该Engine连接资源:

  1. from sqlalchemy.orm import sessionmaker
  2. # 创建session工厂
  3. session_factory= sessionmaker(bind=engine)
  4. # 创建 session 对象
  5. session = session_factory()

session对象的常见操作方法包括:

  1. flush:预提交,提交到数据库文件,还未写入数据库文件中
  2. commit:事务提交
  3. rollback:事务回滚
  4. close:关闭会话

新增数据

  1. # 创建一个学生对象
  2. new_student = Student('John', 18, "Male")
  3. # 将新数据插入到数据库表中
  4. session.add(new_student)
  5. # 事务提交
  6. session.commit()

查询数据

简单数据查询,例如查询所有的学生数据:

session.query(Student)

需要注意的是,这里只构造Query,事实上并没有发送至数据库进行查询,只会在Query.get()、Query.all()、Query.one()以及Query.__iter__等具有“执行”语义的函数,才会真的去获取.所以完整的语句是:

  1. all_students = session.query(Student).all()
  2. print(len(all_students))
  3. # 由于数据库中只有一条数据,所以此处输出数据是 1

单数据表条件查询,例如,查询编号为1的学生信息

  1. # 单数据表条件查询,查询id为1的学生
  2. criteria_students = session.query(Student).filter_by(id=1).all()
  3. print(len(criteria_students))
  4. # 或
  5. # 单数据表条件查询,查询id为1的学生
  6. criteria_students = session.query(Student).filter(Student.id == 1).all()
  7. print(len(criteria_students))

query有filter和filter_by两个过滤方法,通常这两个方法都会用到的,所以一定要掌握它们的区别:

filterfilter_by
支持所有比较运算符,等值比较用 ==只能使用 = ,!= , >, <
过滤条件使用 类名.属性名 的形式过滤条件使用 属性名
不支持组合查询,只能连续调用filter变相实现参数是 **kwargs,支持组合查询
支持and、or和in等操作 

修改数据

数据修改操作同样有两种方式,批量修改或同时需要修改多个属性时,例如同时修改age和gender(举个栗子),直接使用第一种方法传入字典数据即可{ "age" : 20, "gender" : "Female" }

  1. # 第一种修改方式
  2. session.query(Student).filter_by(id=1).update({"age": 20})
  3. session.commit()
  4. # 第二种修改方式
  5. stu = session.query(Student).filter_by(id=1).first()
  6. stu.age = 20
  7. session.add(stu)
  8. session.commit()

删除数据

  1. # 第一种删除方式
  2. del_stu = session.query(Student).filter_by(id=1).first()
  3. if del_stu:
  4. session.delete(del_stu)
  5. session.commit()
  6. # 第二种删除方式
  7. session.query(Student).filter_by(id=1).delete()
  8. session.commit()

以上就是SQLAlchemy的简单增删改查操作了。示例源码放在下面:

  1. # -*- coding: UTF-8 -*-
  2. from sqlalchemy import create_engine
  3. from student import Base, Student
  4. from sqlalchemy.orm import sessionmaker
  5. db_link = f'mysql+pymysql://root:aoto123@192.168.1.124:3306/test'
  6. engine = create_engine(db_link)
  7. print(engine)
  8. # 创建数据表
  9. # Base.metadata.create_all(engine)
  10. # 创建session
  11. DbSession = sessionmaker(bind=engine)
  12. session = DbSession()
  13. # 创建一个学生对象
  14. # new_student = Student('John', 18, "Male")
  15. # 将新数据插入到数据库表中
  16. # session.add(new_student)
  17. # 事务提交
  18. # session.commit()
  19. # 查询所有的学生数据
  20. all_students = session.query(Student).all()
  21. print(len(all_students))
  22. # 单数据表条件查询,查询id为1的学生
  23. # criteria_students = session.query(Student).filter_by(id=1).all()
  24. # print(len(criteria_students))
  25. # 单数据表条件查询,查询id为1的学生
  26. # criteria_students = session.query(Student).filter(Student.id == 1).all()
  27. # print(len(criteria_students))
  28. # 第一种修改方式
  29. # session.query(Student).filter_by(id=1).update({"age": 20})
  30. # session.commit()
  31. # 第二种修改方式
  32. # stu = session.query(Student).filter_by(id=1).first()
  33. # stu.age = 20
  34. # session.add(stu)
  35. # session.commit()
  36. # 第一种删除方式
  37. # del_stu = session.query(Student).filter_by(id=1).first()
  38. # if del_stu:
  39. # session.delete(del_stu)
  40. # session.commit()
  41. # 第二种删除方式
  42. # session.query(Student).filter_by(id=1).delete()
  43. # session.commit()

四·工具方法封装

增删改查代码封装

上述代码中关于Student的数据增删改查,类与查询条件的耦合度较高,用于项目中大量使用的话会造成代码比较混乱,这里分享一个简单封装的操作类,水平一般,仅供参考

  1. # -*- coding: UTF-8 -*-
  2. class DatabaseUtil(object):
  3. def __init__(self, session):
  4. """
  5. 初始化工具类
  6. :param session: 数据库连接会话
  7. """
  8. self.db_session = session
  9. def add_obj(self, obj):
  10. """
  11. 插入数据
  12. :param obj: 插入到数据库表记录的映射对象
  13. :return:
  14. """
  15. self.db_session.add(obj)
  16. # 提交即保存到数据库:
  17. self.db_session.commit()
  18. def del_obj(self, class_, *args):
  19. """
  20. 删除数据库记录
  21. :param class_: 数据表所对应的对象类型
  22. :param args: 筛选条件,元组类型
  23. :return:
  24. """
  25. self.db_session.query(class_).filter(args[0] == args[1]).delete()
  26. self.db_session.commit()
  27. def is_obj_exists(self, class_, *args):
  28. """
  29. 查询数据库中是否有数据记录
  30. :param class_: 数据表所对应的对象类型
  31. :param args: 筛选条件,元组类型
  32. :return: 有记录,返回True,否则返回False
  33. """
  34. obj_list = self.db_session.query(class_).filter(args[0] == args[1]).all()
  35. if len(obj_list) > 0:
  36. return True
  37. else:
  38. return False
  39. def insert_or_update(self, class_, *args, **kwargs):
  40. """
  41. 插入或更新一条记录
  42. :param class_: 数据表所对应的对象类型
  43. :param args: 筛选条件,元组类型
  44. :param kwargs: 插入到数据库中的数据记录,字典类型
  45. :return:
  46. """
  47. if self.is_obj_exists(class_, *args):
  48. # update
  49. self.db_session.query(class_).filter(args[0] == args[1]).update(kwargs)
  50. self.db_session.commit()
  51. else:
  52. # insert
  53. obj = class_(**kwargs)
  54. self.add_obj(obj)
  55. @staticmethod
  56. def props(obj):
  57. """
  58. 将class转dict,以_开头的属性不要
  59. :param obj:
  60. :return:
  61. """
  62. pr = {}
  63. for name in dir(obj):
  64. value = getattr(obj, name)
  65. if value is None:
  66. continue
  67. if not name.startswith('_') and not callable(value):
  68. pr[name] = value
  69. return pr

那么这个工具类如何使用呢,这里有个使用示例,请注意,这个工具类在初始化时,直接接收session值作为属性成员,您也可以在工具类直接接收数据库连接参数等数据,自己生成session会话。

实体类修改构造方法

在使用前,修改一下实体类的构造方法,直接转字典类型为class类型,方便操作,如下:

  1. from sqlalchemy import Column, String, Integer
  2. from sqlalchemy.ext.declarative import declarative_base
  3. # 创建对象的基类:
  4. Base = declarative_base()
  5. # 定义User对象:
  6. class Student(Base):
  7. # 表的名字:
  8. __tablename__ = 'STUDENTS'
  9. def __init__(self, **entries):
  10. self.__dict__.update(entries)
  11. # 表的结构:
  12. id = Column(name='stu_id', type_=Integer, primary_key=True, autoincrement=True)
  13. name = Column(name='stu_name', type_=String(20))
  14. age = Column(name='stu_age', type_=Integer)
  15. gender = Column(name='stu_gender', type_=String(20))

工具的使用

  1. from sqlalchemy import create_engine
  2. from sqlalchemy.orm import sessionmaker
  3. from database_test.db_utils import DatabaseUtil
  4. from student import Student
  5. if __name__ == '__main__':
  6. stu_info_1 = {"name": "John", "age": 18, "gender": "Male"}
  7. stu_info_2 = {"name": "Gina", "age": 20, "gender": "Female"}
  8. stu_info_3 = {"name": "Tom", "age": 23, "gender": "Male"}
  9. db_link = f'mysql+pymysql://root:aoto123@192.168.1.124:3306/test'
  10. engine = create_engine(db_link)
  11. # 创建session
  12. DbSession = sessionmaker(bind=engine)
  13. session = DbSession()
  14. # 获取工具对象
  15. db_util = DatabaseUtil(session)
  16. # 字典数据转换为Student对象
  17. new_stu = Student(**stu_info_1)
  18. # 新增
  19. db_util.add_obj(new_stu)
  20. # 新增或更新数据
  21. # 设置查询条件,等同于 where name = "some name" 和 query(Student).filter(name='some name')
  22. criteria = (Student.name, stu_info_1["name"])
  23. # 传入参数,如果这条记录不存在,插入数据,如果已存在,按照传入的数据更新
  24. db_util.insert_or_update(Student, *criteria, **stu_info_1)
  25. # 删除数据
  26. # 设置查询条件,等同于delete ... where name = "some name"
  27. db_util.del_obj(Student, *criteria)
  28. exit(0)

以上代码仅供参考,水平有限,欢迎各位批评指正。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/927219
推荐阅读
相关标签
  

闽ICP备14008679号