简介

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

装置SQLAlchemy也很简略,间接应用pip装置即可。

pip install sqlalchemy

上面重点介绍SQLAlchemy的应用。

版本查看

import sqlalchemysqlalchemy.__version__    # 1.1.9

以后sqlalchemy版本为1.1.9

连贯数据库

from sqlalchemy import create_engineengine = 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_enginefrom sqlalchemy import Column, String, Integerfrom sqlalchemy.ext.declarative import declarative_baseengine = 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)  # 删除所有表# 定义类的实例办法1u1 = User()    # User类只接管一个地位参数self,和关键字参数**kwargsu1.name = 'aa'  # 给User类的各个列赋值u1.age=19print(u1)  # User(id=None, name=aa, age=19)# 定义类的实例办法2u2 = 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 sessionmakerSession = 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 = 20session.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_ageFROM USERWHERE USER.age < % (age_1) sORDER BY USER.age DESCLIMIT % (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 Nonequery.filter(User.name.is_(None))
  • IS NOT NULL

    query.filter(User.name != None)# 下面的写法不合乎pep8标准,IDE会给出提醒,能够用上面的办法代替,pep8的写法是is not Nonequery.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 funcsession.query(func.count(User.id)).first() # countsession.query(func.max(User.age)).first() # maxsession.query(func.avg(User.age)).first() # avg

Relationship

表和表之间会有外键关系,数据库的外键关系在ORM中的应用办法如下:

from sqlalchemy import create_enginefrom sqlalchemy import Column, Integer, Stringfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import sessionmakerfrom sqlalchemy import ForeignKeyfrom sqlalchemy.orm import relationshipBase = 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 = authorsession.add(post)session.commit()print(author.posts)  # [Post<id=1, title=first post>]# 再新增一篇文章post = Post()post.title = 'second post'post.content = 'liabhgekegpaerg'post.author = authorsession.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

记得帮我点赞哦!

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

朝思暮想,必有回响,小伙伴们帮我点个赞吧,非常感谢。

我是职场亮哥,YY高级软件工程师、四年工作教训,回绝咸鱼争当龙头的斜杠程序员。

听我说,提高多,程序人生一把梭

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

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

自己所有文章、答复都与版权保护平台有单干,著作权归职场亮哥所有,未经受权,转载必究!