sqlalchemy的基本用法

  参考原文:https://www.cnblogs.com/blueberry-mint/p/14277882.html

  1 简介

  SQLAlchemy是用Python编程语言开发的一个开源项目。它提供了SQL工具包和ORM(对象关系映射)工具,使用MIT许可证发行。

  SQLAlchemy最初在2006年2月发行,发行后便很快的成为Python社区中最广泛使用的ORM工具之一,丝毫不亚于Django自带的ORM框架。

  SQLAlchemy采用简单的Python语言,提供高效和高性能的数据库访问,实现了完整的企业级持久模型。它的理念是,SQL数据库的量级和性能比对象集合重要,而对象集合的抽象又重要于表和行。

  2 基本用法

  2.1 安装

  安装sqlachemy

pip3 install sqlalchemy
pip3 install pymysql

  本文使用MySQL作为数据库,使用pymysql作为驱动,因此需要安装pymysql

  2.2 连接数据库

  配置信息

  在连接数据库前,需要使用到一些配置信息,然后把它们组合成满足以下条件的字符串:

dialect+driver://username:password@host:port/database

  

  • dialect:数据库,如:sqlite、mysql、oracle等
  • driver:数据库驱动,用于连接数据库的,本文使用pymysql
  • username:用户名
  • password:密码
  • host:IP地址
  • port:端口
  • database:数据库

  建议将这些配置信息放到一个配置文件中,如config.py然后倒入配置文件

  config.py

HOST = '192.168.1.180'
PORT = 3306
USERNAME = 'root'
PASSWORD = 'password'
DB = 'myclass'

# f代表可以使用{}引用变量
DB_URI = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DB}'
# 以下语句和上面语句作用一致
# DB_URI = 'mysql+pymysql://%s:%s@%s:%s/%s'%(USERNAME,PASSWORD,HOST,PORT,DB)

  创建引擎并连接数据库

  注意:本次操作的数据库名为myclass需要提前创建好

from sqlalchemy import create_engine
from config import DB_URI


engine = create_engine(DB_URI)  # 创建引擎
conn = engine.connect()  # 连接
result = conn.execute('SELECT 1')  # 执行SQL
print(result.fetchone())  
conn.close()  # 关闭连接

  这里执行是SQL语句可以参考 https://www.cnblogs.com/minseo/p/15291725.html 是一致的

  创建ORM模型并映射到数据库中

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from config import DB_URI
# print(DB_URI)
# mysql+pymysql://root:password@192.168.1.180:3306/myclass
# 创建引擎
engine = create_engine(DB_URI)
#sconn = engine.connect()
# 创建SQLORM基类,注意这里要加参数,参数为上一步创建的引擎
Base = declarative_base(engine)
# 构建session对象
session = sessionmaker(engine)()

# 创建student表
# 该表有4列分别为自增id name age sex
# 分别代表id 姓名 年龄 性别其中id age为整数 name和sex为字符串
class Student(Base):
    __tablename__ = 'student'  # 表名
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50))
    age = Column(Integer)
    sex = Column(String(10))

# 将模型映射到数据库中
# 即如果数据库中没有student表则创建映射表student
Base.metadata.create_all()

  执行上面代码,将会在数据库中生成对应的映射表student 

  可以登录MySQL查看建表语句

mysql> show create table student;
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                                                    |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 

  注意:如果表结构有修改,例如增加一个字段address

address = Column(String(100))

  再执行不会修改表,只有删除表再执行才会重新创建表并且新增这个字段

  即执行Base.metadata.create_all()是如果数据库里面没有表则创建表,如果有表则不进行操作

  新增数据

  在添加数据之前可以把以下代码注释,因为表已经创建好了,无需执行

Base.metadata.create_all()

  

  创建好表以后,接下来我们要添加数据,代码如下  

# 新增数据
# 创建一个Student对象
student = Student(name='Tony',age=18,sex='male')
# 添加到session
session.add(student)
# 提交到数据库
session.commit()

  添加数据以后查看

mysql> select * from student;
+----+------+------+------+
| id | name | age  | sex  |
+----+------+------+------+
|  1 | Tony |   18 | male |
+----+------+------+------+

  也可以批量添加数据

# 批量添加数据
# 使用add_all()方法传递的参数为list
# list对象为Student对象
session.add_all([
    Student(name='Jane', age=16, sex='female'),
    Student(name='Ben', age=20, sex='male')
])
session.commit()

  查询数据库现在有3条数据了

mysql> select * from student;
+----+------+------+--------+
| id | name | age  | sex    |
+----+------+------+--------+
|  1 | Tony |   18 | male   |
|  2 | Jane |   16 | female |
|  3 | Ben  |   20 | male   |

  查询数据

  sqlalchemy提供了query()方法来查询数据

  获取所有数据

# 查询数据
# 获取所有数据
item_list = session.query(Student).all()
# 获取的是Student对象
print(item_list)
# [<__main__.Student object at 0x000002748DEC2BE0>, <__main__.Student object at 0x000002748DEC2C50>, <__main__.Student object at 0x000002748DEC2CC0>]
# 遍历通过对象的属性打印对应的数据
for item in item_list:
    print(item.name, item.age)
# Tony 18
# Jane 16
# Ben 20

  查询得到的item_list是一个包含多个Student对象的列表

  指定列查询

# 指定列查询
# 指定查询name列
# 类似于执行sql语句select name from student;
item_list = session.query(Student.name).all()
# 查询的数据组成一个list,数据为元组为查询的结果
# 可以指定多个列以,分隔,获取的结果的元组也以,分隔
print(item_list)
# [('Tony',), ('Jane',), ('Ben',)]

  获取返回数据的第一行

# 获取返回数据的第一行
item = session.query(Student.name).first()
print(item)
# ('Tony',)

  使用filter()方法过滤

# 使用filter方法过滤
item_list = session.query(Student.name).filter(Student.age >= 18).all()
print(item_list)

# [('Tony',), ('Ben',)]

  使用order_by()进行排序

# 使用order_by()进行排序
# 使用列name和age查询并且使用age进行倒序
item_list = session.query(Student.name,Student.age).order_by(Student.age.desc()).all()
print(item_list)
# [('Ben', 20), ('Tony', 18), ('Jane', 16)]

  多条件查询

# 多条件查询条件以,分隔默认为and
item_list = session.query(Student.name, Student.age, Student.sex).filter(Student.age >= 10, Student.sex == 'female').all()
print(item_list)

  以上查询语句类似于sql语句

mysql> select name,age,sex from student where age<=16 and sex='female';
+------+------+--------+
| name | age  | sex    |
+------+------+--------+
| Jane |   16 | female |
+------+------+--------+
1 row in set (0.00 sec)

  使用or_连接多个条件

# 以or条件查询
# 需要导入or_
from sqlalchemy import or_
item_list = session.query(Student.name,Student.age,Student.sex).filter(or_(Student.age >=20,Student.sex=='female')).all()
print(item_list)
# [('Jane', 16, 'female'), ('Ben', 20, 'male')]

  equal/like/in

  下面示例查询等于,不等于,like是模糊查询,in是出现是否包含传递参数列表类元素

# equal/like/in
# 等于 查询age等于18的对象
item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age==18).all()
print(item_list)
# [('Tony', 18, 'male')]

# 不等于
item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age != 18).all()
print(item_list)
# [('Jane', 16, 'female'), ('Ben', 20, 'male')]

# like
# 查询名字有有To字符的对象
item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.name.like('%To%')).all()
print(item_list)
# [('Tony', 18, 'male')]

# in
# 查询age为16或者20的对象,不是16到20的区间
# 注意这里in后面有一个_符号
item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age.in_([16,20])).all()
print(item_list)
# [('Jane', 16, 'female'), ('Ben', 20, 'male')]

  count计算个数

# count计算个数
count = session.query(Student).count()
print(count)
# 3

  切片

# 切片,和Python切片方法一样
item_list = session.query(Student.name).all()[:2]
print(item_list)  
# [('Tony',), ('Jane',)]

  修改数据

   修改数据可以使用update()方法,update完成后记得执行session.commit()

# 修改数据
# 把Tony的age修改为22
# 先查询对象,filter设置过滤条件,update修改数据
session.query(Student).filter(Student.name=='Tony').update({'age':22})
session.commit()

  删除数据

   删除数据使用delete()方法,同样也需要执行session.commit()提交事务

# 删除数据
session.query(Student).filter(Student.name=='Tony').delete()
session.commit()

  注意:增删改查除了查询不设计修改操作,其他增删改都需要使用commit()方法提交事务

posted @ 2021-09-17 15:49  minseo  阅读(1345)  评论(3编辑  收藏  举报