在Flask的应用程序中会使用到sqlarchemy来管理数据库,orm具有如下的几个优点,分别是:
1、灵活性好,它支持原生的SQL语句,但是使用更多的是高层对象来操作数据库。
2、提升效率,从高层对象转换成SQL会牺牲一部分的性能,但是牺牲的这些性能基本可以忽略
不计,反而它会为程序的操作带来很大的效率提升; 。
3、可移植性好,ORM支持多种DBMS,分别如MySQL等数据库。
在实际的开发工作中,与数据库的交互是最常见的交互,那么本文章主要来总结在Flask
应用程序中连接MySQL数据库的操作。在Flask的应用程序中,如果操作数据库需要单独的安
装sqlalchemy的库,安装的命令为:
安装成功后,需要在本地的环境安装MySQL的数据库,这里不在详细的讲解MySQL的安装和
基本的配置,在MySQL的数据库中创建数据库app,也就是数据库的名称是app。下来在Flask
的程序中连接MySQL的操作。下面看具体的代码:
from sqlalchemy import create_engine,Column,Integer,String
from sqlalchemy.ext.declarative import declarative_base
def db_url():
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'app'
USERNAME = 'root'
PASSWORD = 'server'
DB_URL = 'mysql+pymysql://{user}:{passwd}@{host}:{port}/{db}?charset=utf8'.format(
user=USERNAME,
passwd=PASSWORD,
host=HOSTNAME,
port=PORT,
db=DATABASE)
return DB_URL
# 创建引擎
engine = create_engine(db_url())
# 绑定数据库
SqlBase = declarative_base(engine)
class User(SqlBase):
__tablename__='user'
id=Column(Integer,primary_key=True)
username=Column(String(20))
password=Column(String(12))
def __str__(self):
return '<User(username:%s,password:%s)>'%(self.username,self.password)
#创建好的数据模型,映射到数据库中
SqlBase.metadata.create_all()
if __name__ == '__main__':
app.run()
执行如上的代码后,会在MySQL的数据库里面的app数据库中创建user的表,具体见如下的MySQL
的截图:
在Flask中对数据库的操作不能仅仅限于创建数据库中的表,主要是对表的操作,比如插入数据,查询
数据,和修改数据,以及删除数据的操作。下面就实现对MySQL表的增删改查。下面主要对查询的语句进
行总结,在MySQL的查询中,查询使用到的语句是select,在Flask的应用程序中,查询使用到的方法是query,
这里首先对user表里面插入多条数据,依据插入的数据来演示查询结果。 user表插入语句后,显示的结果
如下:
下面写一个函数来对user里面的表的数据进行查询,在查询中,使用到的方法是filter,在filter是过滤条件,
下面依次演示这些,见编写的函数源码:
from flask import Flask,request,render_template,url_for,redirect,jsonify,abort,Response,make_response
from flask import make_response
app = Flask(__name__)
app.config.update({
'DEBUG': True,
'TEMPLATES_AUTO_RELOAD': True
})
from sqlalchemy import create_engine,Column,Integer,String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
def db_url():
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'app'
USERNAME = 'root'
PASSWORD = 'server'
DB_URL = 'mysql+pymysql://{user}:{passwd}@{host}:{port}/{db}?charset=utf8'.format(
user=USERNAME,
passwd=PASSWORD,
host=HOSTNAME,
port=PORT,
db=DATABASE)
return DB_URL
# 创建引擎
engine = create_engine(db_url())
# 绑定数据库
SqlBase = declarative_base(engine)
session=sessionmaker(engine)()
class User(SqlBase):
__tablename__='user'
id=Column(Integer,primary_key=True)
username=Column(String(20))
password=Column(String(12))
def __str__(self):
return '<User(username:%s,password:%s)>'%(self.username,self.password)
#创建好的数据模型,映射到数据库中
SqlBase.metadata.create_all()
def dbSearch():
'''数据的查询'''
result=session.query(User)
print(result)
dbSearch()
执行dbSearch函数后,会打印出在MySQL中查询的依据,见如下截图:
在query查询的时候,后面不加all(),会直接打印出sql的语句,这里是查询所有的数据,加all()后,见打印的输出内容:
def dbSearch():
'''数据的查询'''
result=session.query(User).all()
print(result)
dbSearch()
执行后,见打印输出的内容:
下面加入一些查询条件,如查询username是wuya的用户,那么这里会使用到filter的函数,完善后的函数为:
def dbSearch():
'''数据的查询'''
result=session.query(User).filter(User.username=='wuya').all()
print(result)
dbSearch()
执行后会查询出username为wuya的值的数据,如果下图所示:
继续看查询的条件,在查询中经常会遇到多个条件成立时查询出结果,会使用到and,这里结合案例来看下,见完善后的代码:
def dbSearch():
'''数据的查询'''
result=session.query(User).filter(User.username=='wuya',User.password=='admin').all()
print(result)
dbSearch()
执行后,会查询到username是wuya同时password是admin,如下图所示:
这里再来看下or的条件,就是多个条件中只有满足一个条件就可以了,使用or的时候需要导入,具体见如下的源码:
def dbSearch():
'''数据的查询'''
result=session.query(User).filter(or_(User.username=='wuya',User.password=='admin')).all()
print(result)
dbSearch()
执行后,见查询的结果:
下来结合具体的案例来讲解query查询函数的应用,也就是ORM在实际操作中对表的查询操作,创建表book,并且对该表插入响应的数据,具体见源码:
from sqlalchemy import create_engine,Column,Integer,String,Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
def db_url():
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'app'
USERNAME = 'root'
PASSWORD = 'server'
DB_URL = 'mysql+pymysql://{user}:{passwd}@{host}:{port}/{db}?charset=utf8'.format(
user=USERNAME,
passwd=PASSWORD,
host=HOSTNAME,
port=PORT,
db=DATABASE)
return DB_URL
def Base():
# 创建引擎
engine = create_engine(db_url())
# 绑定数据库
SqlBase = declarative_base(engine)
return SqlBase
def sqlSession():
engine = create_engine(db_url())
session = sessionmaker(engine)()
return session
class Book(Base()):
__tablename__='book'
id=Column(Integer,primary_key=True,autoincrement=True)
name=Column(String(50),nullable=True)
price=Column(Float,nullable=True)
author=Column(String(20),nullable=True)
#创建好的数据模型,映射到数据库中
Base().metadata.drop_all()
Base().metadata.create_all()
def add_books():
book1=Book(name='Flask',price=90,author='wuya')
book2 = Book(name='Django', price=56, author='wuya')
book3 = Book(name='Tornado', price=78, author='wuya')
sqlSession().add_all([book1,book2,book3])
sqlSession().commit()
下面主要依据如上添加的数据,来讲解limit,offset的应用,前者是对返回的数据做限制,后者是对查找的数据做过滤,
比如从第几条开始查询数据。
def query_limit():
'''对返回的数据做限制:limit的应用'''
book=sqlSession().query(Book).limit(2).all()
print(book)
def query_offset():
'''对返回的数据做限制:limit的应用'''
book=sqlSession().query(Book).offset(1).limit(2).all()
print(book)
见执行后返回的结果信息:
再来看切片的操作,使用到的方法是slice的方法,它有点像列表当中的切片一样,总的来说,使用它可以得到获取一定范围内
想要的数据,见案例源码:
def query_slice():
'''slice切片的应用'''
book=sqlSession().query(Book).slice(0,2).all()
print(book)
接着来看query中的排序,排序在原生的SQL中使用到的方法是order_by,和desc以及asc来进行的,依然已book的数据
为案例,以价格的高低来进行排序,见该表中的本身数据,如下图所示:
在sqlalchemy中,排序主要分为三类,第一种就是order_by来进行排序,第二种是在创建的表中就指定按那个字段来
进行排序,这里先看第一中的情况,见该函数的源码:
def order_by():
'''排序的演示代码'''
book=sqlSession().query(Book).order_by('price').all()
print(book)
默认是升序,也就是从小到达,见执行的数据排序:
对程序的代码做以修改,实现倒叙,也就是从大到小,只需要加desc()的函数就可以了,见修改后的代码:
接着来看在创建的表中指定排序的字段,这里就会使用到函数的类属性,以价格作为排序,见实现的源码:
class Book(Base()):
__tablename__='book'
id=Column(Integer,primary_key=True,autoincrement=True)
name=Column(String(50),nullable=True)
price=Column(Float,nullable=True)
author=Column(String(20),nullable=True)
__mapper_args__={
'order_by':price.desc()
}
def __repr__(self):
return '<Book(name:%s,price:%s,author:%s)>'%(self.name,self.price,self.author)
这样查询出的数据,就会以价格的方式,倒叙的方式进行排序。