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://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)
__init__
,会自动的接受咱们所定义的列对应的关键字参数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
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
和insert相似,都是使用session.add方法,可是update操做的时候须要数据库中存在带操做的记录。
user.age = 20 session.add(user) try: session.commit() except Exception as e: session.rollback() raise e
删除以前必须确保数据库中存在要删除的记录。
session.delete(user) # user必须已经存在 try: session.commit() except Exception as e: session.rollback() raise e
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
表和表之间会有外键关系,数据库的外键关系在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>]
数据库维护数据之间的外键关系会消耗数据库资源,影响性能,在大型的应用中通常不使用外键等数据库高级特性,而是由应用框架来维护数据之间的约束。
参考
记得帮我点赞哦!
精心整理了计算机各个方向的从入门、进阶、实战的视频课程和电子书,按照目录合理分类,总能找到你须要的学习资料,还在等什么?快去关注下载吧!!!
念念不忘,必有回响,小伙伴们帮我点个赞吧,很是感谢。
我是职场亮哥,YY高级软件工程师、四年工做经验,拒绝咸鱼争当龙头的斜杠程序员。
听我说,进步多,程序人生一把梭
若是有幸能帮到你,请帮我点个【赞】,给个关注,若是能顺带评论给个鼓励,将不胜感激。
职场亮哥文章列表:更多文章
本人全部文章、回答都与版权保护平台有合做,著做权归职场亮哥全部,未经受权,转载必究!