在学习sqlalchemy之前我们需要首先明白什么是ORM
ORM : object relationship mapping(对象关系映射),也就是程序中的对象与数据库中的表之间的映射模型
其对应关系如下表所示
对应关系 | python中 | 数据库中 |
---|---|---|
1 | 类(class) | 表 |
2 | 对象(object) | 表中一行 |
3 | 一个参数 | 一个字段 |
详细的ORM介绍参考:orm百度百科
1、建立与数据库的链接关系
在使用sqlalchemy进行数据库操作时,由于我们需要操作数据库中的数据,所以我们首先需要做的就是与数据库建立连接,sqlalchemy建立数据库链接的方式为:
# 我们在sqlalchemy中与数据库建立的链接默认称之为 engine
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://{}:{}@{}:{}/{}?charset={}".formate(user,password,ip,port,database_name),echo=True)
'''echo参数的含义是在运行sqlalchemy时将对应的sql语句使用python自带的日志模块进行打印'''
lazy connecting
:在这里必须要提的是sqlalchemy
的懒连接模式,当我们调用create_engine
返回一个engine
对象的时候,sqlalchemy
不会马上去连接数据库,而是在需要执行相关的操作的时候才会真正的去连接数据库
2、与数据库建立映射关系
在我们连接上数据库之后我们就需要与数据库中的表建立映射关系了,如果我们想与数据库中的表建立映射关系,就需要继承sqlalchemy
中的一个Base
类,而这个类由一个元类产生
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
# declarate : 声明
在产生了Base类
之后我们只需要将我们自定义的模型类继承自这个Base类
就可以将类与数据库中的表建立连接关系
from sqlalchemy import Column, Interger, String
class Test(Base): # Base类就是上方定义的Base类
__tablename__ = 'test'
id = Column(Interger, primary_key=True, autoincrement=True)
name = Column(String)
age = Column(String)
def __repr__(self):
id_obj = hex(id(self))
return '<object of Test in %s>'%id_obj
此时,映射关系已经创建完成,创建完成后如果我们想在数据库中生成相应的表,那么就需要使用metadata
(元数据),metadata
是一个包含了有限个操作指令的注册表,使用其create_all
方法可以在数据库中产生一个表
# 在数据库中生成相应的数据表
Base.metadata.create_all(engine)
# 在数据库中删除相应的数据表
Base.metadata.drop_all(engine)
- 如果我们想要对生成了的某张表进行更新时,此时有两种方法,一个是将整张表删除后重新创建,另一中方法是使用一个新的模块,名字叫做
alembic
,这个模块是sqlalchemy的作者写的,现在我还没看只是知道有这个模块的存在,后续再进行补充
- 重要: 有时候我们想要为已经存在的表建立一个model类进行映射,此时我们可以使用另一个模块进行,这个模块叫做
sqlacodegen
使用方法为:sqlacodegen [--tables 表名] mysql://username:password@ip/database_name
3、创建会话
当我们创建了数据库连接(engine)以及映射关系之后,我们就需要对数据库进行相应的操作了,但在对数据库进行操作之前我们还需要创建一个会话,这个会话的创建是与连接的创建处于同一级的
from sqlalchemy.orm import sessionmaker
# 在创建会话类时就指定数据库
Session = sessionmaker(bind=engine)
# 在创建会话时不指定数据库,而后根据会话的配置文件指定数据库
Session = sessionmaker()
Session.configure(bind=engine)
此时,一个会话类就创建完成了,如果我们需要对数据库进行操作,那么我们只需要实例化这个类就可以了
session = Session()
# session的方法有四个:
flush:预提交,不会存储到数据库中
commit:提交一个事务,数据保存到了数据库
rollback:撤回,当事务报错时需要使用rollback进行撤回,否则下次操作会报错
close:关闭会话,在完成操作后要关闭当前的会话
sqlalchemy 错误信息总结
1. 使用sqlalchemy 时, 数据库连接数越来越多
描述: 使用sqlalchemy 时对查询语句进行了封装, 在封装中队sqlalchemy 的session做了close处理,但是数据库中显示连接数量越来越多
原因: sqlalchemy真正的进行数据库查询时在 .all() 或者 .first()时, 如果我们在封装时未在 使用这个方法时就使用session.close(), 此时数据库连接还没有建立, 所以此时session的关闭时无效的, 在执行.all()/.first()方法时真正的建立了连接, 所以建立的连接就不能关闭了。
2. 使用sqlalchemy 执行原生语句时报错
描述: 使用sqlalchemy执行原生语句时遇到 like语句时,报错 ValueError: unsupported format character '?'
参考:https://stackoverflow.com/questions/63077106/valueerror-in-mysql-python-sqlalchemy-query
原因: 在执行like语句时, 由于%的原因, 需要对查询内容先进行占位, 再使用参数替换的方式进行处理, 这样也可以避免sql注入
解决:
原始sql: select * from table where name like '%小明%'
执行: pd.read_sql(sql, engine)
更新后sql: select * from table where name like :name1
执行:pd.read_sql(sql, engine, params={'name1': f"%小明%"})
网友评论