共计 5874 个字符,预计需要花费 15 分钟才能阅读完成。
简介
SQLAlchemy 是 Python 语言的一款风行的 ORM(Object Relational Mapper)框架,该框架建设在数据库 API 之上,应用关系对象映射进行数据库操作,行将对象转换成 SQL,而后应用数据 API 执行 SQL 并获取执行后果。
装置 SQLAlchemy 也很简略,间接应用 pip 装置即可。
pip install sqlalchemy
上面重点介绍 SQLAlchemy 的应用。
版本查看
import sqlalchemy
sqlalchemy.__version__ # 1.1.9
以后 sqlalchemy 版本为 1.1.9
连贯数据库
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True)
- engine 是 Engine 类的一个对象
- echo=True 表明开启 logging 模块的日志
- 数据库连贯:
engine://user:password@host:port/database
,其中 engine 为 mysql+pymysql,或者是 mysql+mysqldb,或者是 oracle+cx_oracle 等等
<!–more–>
创立表
from sqlalchemy import create_engine
from sqlalchemy import Column, String, Integer
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True)
Base = declarative_base() # 生成 Model 类的基类
class User1(Base):
__tablename__ = 'user1'
extend_existing = True
# 定义三个列
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(String(64), unique=True, nullable=False)
age = Column(Integer)
def __repr__(self):
return 'User(id={}, name={}, age={})'.format(self.id, self,name, self.age)
def __str__(self):
return self.__repr__()
Base.metadata.create_all(engine) # 创立所有表
Base.metadata.drop_all(engine) # 删除所有表
# 定义类的实例办法 1
u1 = User() # User 类只接管一个地位参数 self,和关键字参数 **kwargs
u1.name = 'aa' # 给 User 类的各个列赋值
u1.age=19
print(u1) # User(id=None, name=aa, age=19)
# 定义类的实例办法 2
u2 = User(name='bb', age='123')
print(u2) # User(id=None, name=bb, age=123)
- 派生类 User 会继承基类 Base 的初始化函数
__init__
,会主动的承受咱们所定义的列对应的关键字参数 - 未赋值的列会用 None 初始化,如下面的 id
Session
SQLAlchemy 真正解决数据库的局部是 Session。
如果曾经创立好了一个 Engine 对象 engine,那么能够用以下语句创立一个 Session
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
如果 engine 为创立好,则能够用以下语句创立
Session = sessionmaker()
当 engine 创立好之后,在配置 Session 即可
Session.configure(bind=engine)
当须要和数据库交互的时候,就须要实例化 Session
session = Session()
创立实现之后这个 session 并没有马上获取数据库连贯。只有当这个 session 第一次操作数据库的时候才会从 Engine 保护的连接池中获取一个连贯,并持有这个连贯始终到咱们提交了所有的扭转或者敞开了这个 session。
DML
insert
user = User(name='haha', age='123')
session.add(user)
session.commit()
如果这个 commit 的过程中产生异样,则后续所有的 commit 都无奈执行,因而 DML 都须要放在 try…except 中解决,如下
user = User(name='flowsnow', age=18)
session.add(user)
try:
session.commit()
except Exception as e:
session.rollback()
raise e
update
和 insert 相似,都是应用 session.add 办法,然而 update 操作的时候须要数据库中存在带操作的记录。
user.age = 20
session.add(user)
try:
session.commit()
except Exception as e:
session.rollback()
raise e
delete
删除之前必须确保数据库中存在要删除的记录。
session.delete(user) # user 必须曾经存在
try:
session.commit()
except Exception as e:
session.rollback()
raise e
QUERY
for u in session.query(User).filter(User.age < 20).order_by(User.age.desc())[1:3]:
print(u)
此条语句经 ORM 转换之后的 SQL 如下:
SELECT
USER.id AS user_id,
USER.NAME AS user_name,
USER.age AS user_age
FROM USER
WHERE USER.age < % (age_1) s
ORDER BY USER.age DESC
LIMIT % (param_1) s, % (param_2) s
query 函数的返回后果为一个 Query 对象,Query 对象是可迭代的,反对切片操作。
上面列举常见的 filter 操作
-
相等
query.filter(User.name == 'suncle')
-
不相等
query.filter(User.name != 'suncle')
-
含糊匹配 like:大小写敏感
query.filter(User.name.like('%sun%'))
-
含糊匹配 ilike:大小写不敏感
query.filter(User.name.ilike('%sun%'))
-
IN
query.filter(User.name.in_(['suncle', 'abc', 'suncle'])) # 也反对 Query 对象 query.filter(User.name.in_(session.query(User.name).filter(User.name.like('%sun%')) ))
-
NOT IN
query.filter(~User.name.in_(['ed', 'wendy', 'jack']))
-
IS NULL
query.filter(User.name == None) # 下面的写法不合乎 pep8 标准,IDE 会给出提醒,能够用上面的办法代替,pep8 的写法是 is None query.filter(User.name.is_(None))
-
IS NOT NULL
query.filter(User.name != None) # 下面的写法不合乎 pep8 标准,IDE 会给出提醒,能够用上面的办法代替,pep8 的写法是 is not None query.filter(User.name.isnot(None))
-
AND
# 办法 1:应用 and_() 办法 from sqlalchemy import and_ query.filter(and_(User.name == 'flowsnow', User.age == 18)) # 办法 2:filter() 反对多个关键字参数 query.filter(User.name == 'flowsnow', User.age == 18) # 办法 3:屡次调用 filter 函数 query.filter(User.name == 'flowsnow').filter(User.age == 18)
-
OR
from sqlalchemy import or_ query.filter(or_(User.name == 'suncle', User.name == 'flowsnow'))
上面列举 SQL 反对的常见的 function
from sqlalchemy import func
session.query(func.count(User.id)).first() # count
session.query(func.max(User.age)).first() # max
session.query(func.avg(User.age)).first() # avg
Relationship
表和表之间会有外键关系,数据库的外键关系在 ORM 中的应用办法如下:
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
Base = declarative_base() # 生成 Model 类的基类
class Author(Base): # 作者类
__tablename__ = 'author'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), unique=True, nullable=False)
posts = relationship('Post')
def __repr__(self):
return 'Author<id={},name={}>'.format(self.id, self.name)
def __str__(self):
return self.__repr__()
class Post(Base): # 文章类
__tablename__ = 'post'
id = Column(Integer, primary_key=True, autoincrement=True)
title = Column(String(128), nullable=False, index=True)
content = Column(String(8096), nullable=False)
author_id = Column(Integer, ForeignKey('author.id'), nullable=False)
author = relationship('Author')
def __repr__(self):
return 'Post<id={}, title={}>'.format(self.id, self.title)
def __str__(self):
return self.__repr__()
engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# 新增一个作者
author = Author()
author.name = 'flowsnow'
session.add(author)
session.commit()
print(author) # Author<id=1,name=flowsnow>
# 新增一篇文章
post = Post()
post.title = 'first post'
post.content = 'oihdoshfohro'
post.author = author
session.add(post)
session.commit()
print(author.posts) # [Post<id=1, title=first post>]
# 再新增一篇文章
post = Post()
post.title = 'second post'
post.content = 'liabhgekegpaerg'
post.author = author
session.add(post)
session.commit()
print(author.posts) # [Post<id=1, title=first post>, Post<id=2, title=second post>]
数据库保护数据之间的外键关系会耗费数据库资源,影响性能,在大型的利用中个别不应用外键等数据库高级个性,而是由利用框架来保护数据之间的束缚。
参考
- 官网文档 -Object Relational Tutorial
- A step-by-step SQLAlchemy tutorial
- 廖雪峰 - 应用 SQLAlchemy
记得帮我点赞哦!
精心整顿了计算机各个方向的从入门、进阶、实战的视频课程和电子书,依照目录正当分类,总能找到你须要的学习材料,还在等什么?快去关注下载吧!!!
朝思暮想,必有回响,小伙伴们帮我点个赞吧,非常感谢。
我是职场亮哥,YY 高级软件工程师、四年工作教训,回绝咸鱼争当龙头的斜杠程序员。
听我说,提高多,程序人生一把梭
如果有幸能帮到你,请帮我点个【赞】,给个关注,如果能顺带评论给个激励,将不胜感激。
职场亮哥文章列表: 更多文章
自己所有文章、答复都与版权保护平台有单干,著作权归职场亮哥所有,未经受权,转载必究!