SQLAlchemy使用

简介

SQLAlchemy是Python语言的一款流行的ORM(Object Relational Mapper)框架,该框架创建在数据库API之上,使用关系对象映射进行数据库操做,即将对象转换成SQL,而后使用数据API执行SQL并获取执行结果。html

安装SQLAlchemy也很简单,直接使用pip安装便可。python

pip install sqlalchemy

下面重点介绍SQLAlchemy的使用。mysql

版本检查

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等等

建立表

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。sql

若是已经建立好了一个Engine对象engine,那么能够用如下语句建立一个Sessionshell

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)

若是engine为建立好,则能够用如下语句建立数据库

Session = sessionmaker()

当engine建立好以后,在配置Session便可session

Session.configure(bind=engine)

当须要和数据库交互的时候,就须要实例化Sessionoracle

session = Session()

建立完成以后这个session并无立刻获取数据库链接。只有当这个session第一次操做数据库的时候才会从Engine维护的链接池中获取一个链接,并持有这个链接一直到咱们提交了全部的改变或者关闭了这个session。app

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>]

数据库维护数据之间的外键关系会消耗数据库资源,影响性能,在大型的应用中通常不使用外键等数据库高级特性,而是由应用框架来维护数据之间的约束。


参考

  1. 官方文档-Object Relational Tutorial
  2. A step-by-step SQLAlchemy tutorial
  3. 廖雪峰-使用SQLAlchemy

记得帮我点赞哦!

精心整理了计算机各个方向的从入门、进阶、实战的视频课程和电子书,按照目录合理分类,总能找到你须要的学习资料,还在等什么?快去关注下载吧!!!

resource-introduce

念念不忘,必有回响,小伙伴们帮我点个赞吧,很是感谢。

我是职场亮哥,YY高级软件工程师、四年工做经验,拒绝咸鱼争当龙头的斜杠程序员。

听我说,进步多,程序人生一把梭

若是有幸能帮到你,请帮我点个【赞】,给个关注,若是能顺带评论给个鼓励,将不胜感激。

职场亮哥文章列表:更多文章

wechat-platform-guide-attention

本人全部文章、回答都与版权保护平台有合做,著做权归职场亮哥全部,未经受权,转载必究!

相关文章
相关标签/搜索