在这里插入代码片## ORM
ORM 全拼Object-Relation Mapping
,中文意为 对象-关系映射。主要实现模型对象到关系数据库数据的映射
优点 :
sql语句
.缺点 :
flask默认提供模型操作,但是并没有提供ORM,所以一般开发的时候我们会采用flask-SQLAlchemy模块来实现ORM操作。
SQLAlchemy是一个关系型数据库框架,它提供了高层的 ORM 和底层的原生数据库的操作。flask-sqlalchemy 是一个简化了 SQLAlchemy 操作的flask扩展。
SQLAlchemy: https://www.sqlalchemy.org/
中文文档: https://www.osgeo.cn/sqlalchemy/index.html
安装 flask-sqlalchemy【清华源】
pip install flask-sqlalchemy -i https://pypi.tuna.tsinghua.edu.cn/simple
如果连接的是 mysql 数据库,需要安装 mysqldb 驱动
pip install flask-mysqldb -i https://pypi.tuna.tsinghua.edu.cn/simple
安装flask-mysqldb时,注意
安装 flask-mysqldb的时候,python底层依赖于一个底层的模块 mysql-client模块
如果没有这个模块,则会报错如下:
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-21hysnd4/mysqlclient/
解决方案:
sudo apt-get install libmysqlclient-dev python3-dev
运行上面的安装命令如果再次报错如下:
dpkg 被中断,您必须手工运行 ‘sudo dpkg --configure -a’ 解决此问题。
则根据提示执行命令以下命令,再次安装mysqlclient
sudo dpkg --configure -a
apt-get install libmysqlclient-dev python3-dev
解决了mysqlclient问题以后,重新安装 flask-mysqldb即可。
pip install flask-mysqldb -i https://pypi.tuna.tsinghua.edu.cn/simple
在 Flask-SQLAlchemy 中,数据库使用URL指定,而且程序使用的数据库必须保存到Flask配置对象的 SQLALCHEMY_DATABASE_URI 键中
config.py,配置文件代码:
class Config(object):
DEBUG = True
SECRET_KEY = "*(%#4sxcz(^(#$#8423"
# 数据库链接配置 = 数据库名称://登录账号:登录密码@数据库主机IP:数据库访问端口/数据库名称?charset=编码类型
SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]:3306/students?charset=utf8mb4"
其他设置:
# 动态追踪修改设置,如未设置只会提示警告
SQLALCHEMY_TRACK_MODIFICATIONS = True
#查询时会显示原始SQL语句
SQLALCHEMY_ECHO = True
配置完成需要去 MySQL 中创建项目所使用的数据库
mysql -uroot -p123
mysql > create database students charset=utf8mb4;
模型字段类型名 | python中数据类型 | 说明 |
---|---|---|
Integer | int | 普通整数,一般是32位 |
SmallInteger | int | 取值范围小的整数,一般是16位 |
BigInteger | int或long | 不限制精度的整数 |
Float | float | 浮点数 |
Numeric | decimal.Decimal | 普通数值,一般是32位 |
String | str | 变长字符串 |
Text | str | 变长字符串,对较长或不限长度的字符串做了优化 |
LongText | str | 长文本类型 |
Unicode | unicode | 变长Unicode字符串 |
UnicodeText | unicode | 变长Unicode字符串,对较长或不限长度的字符串做了优化 |
Boolean | bool | 布尔值 |
Date | datetime.date | 日期 |
Time | datetime.time | 时间 |
DateTime | datetime.datetime | 日期和时间 |
DECIMAL | decimal.Decimal | 定点类型 |
Enum | str | 枚举类型 |
选项名 | 说明 |
---|---|
primary_key | 如果为True,代表表的主键 |
unique | 如果为True,代表这列不允许出现重复的值 |
index | 如果为True,为这列创建索引,提高查询效率 |
nullable | 如果为True,允许有空值,如果为False,不允许有空值 |
default | 为这列定义默认值 |
autoincrement | 是否自动增长 |
onupdate | 更新的时候执行的函数 |
name | 该属性在数据库中的字段映射 |
query可以参数:
选项名 | 说明 |
---|---|
func.count | 统计行的数量 |
func.avg | 求平均值 |
func.max | 求最大值 |
func.min | 求最小值 |
func.sum | 求和 |
过滤方法:
过滤是数据 提取的一个很重要的功能,以下对一些常用的过滤条件进行详解,并且这些过滤条件都是只能通过filter方法实现的:
query.filter(User.name == 'ed')
query.filter(User.name != 'ed')
query.filter(User.name.like('%ed%'))
query.filter(User.name.in_(['ed','wendy','jack']))
#同时
query.filter(User.name.in_(session.query(User.name).filter(User.name.like('%ed%'))))
query.filter(~User.name.in_('ed','wendy','jack'))
query.filter(User.name==None)
query.filter(User.name.is_(None))
query.filter(User.name != None)
query.filter(User.name.isnot(None)
from sqlalchemy import and_
query.filter(and_(User.name=='ed', User.fullname=='Ed Jones'))
# 或者
query.filter(User.name=='ed', User.fullname=='Ed Jones')
# 或者
query.filter(User.name=='ed',).filter(User.fullname=='Ed Jones')
from sqlalchemy import or_
query.filter(or_(User.name='ed', User.name='wendy'))
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__, template_folder='templates')
class Config(object):
DEBUG = True
SECRET_KEY = os.urandom(24) # 随机生成一个密钥
# 数据库链接配置 = 数据库名称://登录账号:登录密码@数据库主机IP:数据库访问端口/数据库名称?charset=编码类型
SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]:3306/students?charset=utf8mb4"
# 动态追踪修改设置,如未设置只会提示警告
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 查询时会显示原始SQL语句
SQLALCHEMY_ECHO = True
app.config.from_object(Config)
# 初始化SQLAlchemy
db = SQLAlchemy() # 初始化数据库操作对象
db.init_app(app) # 初始化数据库链接
# 创建模型类
class Student(db.Model):
# 表结构声明
__tablename__ = "tb_student"
# 字段声明
id = db.Column(db.Integer, primary_key=True, comment="主键ID") # 字段类型
name = db.Column(db.String(250), comment="姓名")
age = db.Column(db.Integer, comment="年龄")
sex = db.Column(db.Boolean, default=False, comment="性别")
# DECIMAL设置小数精度,最多八位小数点后面两位 ,允许有空值,comment为列注释
money = db.Column(db.DECIMAL(8,2), nullable=True, comment="钱包")
def __repr__(self): # 定义 __repr__ 是为了方便调试,你可以不定义,也可以定义的更详细一些。
return self.name
class Teacher(db.Model):
__tablename__ = "tb_teacher"
id = db.Column(db.Integer, primary_key=True, comment="主键ID")
name = db.Column(db.String(250), comment="姓名")
sex = db.Column(db.Boolean, default=False, comment="性别")
option = db.Column(db.Enum("老师", "助教", "班主任"), default="老师", comment="职位")
def __repr__(self): # 定义 __repr__ 是为了方便调试,你可以不定义,也可以定义的更详细一些。
return self.name
class Course(db.Model):
__tablen__ = "tb_course"
id = db.Column(db.Integer, primary_key=True, comment="主键ID")
name = db.Column(db.String(250),comment="课程名称")
price = db.Column(db.Numeric(6.2)) # 设置小数精度,一共6位小数点后面2位
def __repr__(self):
return self.name
@app.route('/')
def index():
return 'ok'
if __name__ == '__main__':
# with app.app_context():
# db.create_all() # 根据模型创建所有的数据表
# # db.drop_all() # 删除模型对应的所有数据表
app.run()
创建表
db.create_all()
注意,create_all()方法执行的时候,需要放在模型的后面
上面这段语句,后面我们需要转移代码到flask-script的自定义命令中。
执行了一次以后,需要注释掉。
删除表
db.drop_all()
代码:
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__, template_folder='templates')
class Config(object):
DEBUG = True
SECRET_KEY = os.urandom(24) # 随机生成一个密钥
# 数据库链接配置 = 数据库名称://登录账号:登录密码@数据库主机IP:数据库访问端口/数据库名称?charset=编码类型
SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]:3306/students?charset=utf8mb4"
# 动态追踪修改设置,如未设置只会提示警告
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 查询时会显示原始SQL语句
SQLALCHEMY_ECHO = True
app.config.from_object(Config)
# 初始化SQLAlchemy
db = SQLAlchemy() # 初始化数据库操作对象
db.init_app(app) # 初始化数据库链接
# 创建模型类
class Student(db.Model):
# 表结构声明
__tablename__ = "tb_student"
# 字段声明
id = db.Column(db.Integer, primary_key=True, comment="主键ID") # 字段类型
name = db.Column(db.String(250), comment="姓名")
age = db.Column(db.Integer, comment="年龄")
sex = db.Column(db.Boolean, default=False, comment="性别")
# DECIMAL设置小数精度,一共八位小数点后面两位 ,允许有空值,comment为列注释
money = db.Column(db.DECIMAL(8,2), nullable=True, comment="钱包")
def __repr__(self): # 定义 __repr__ 是为了方便调试,你可以不定义,也可以定义的更详细一些。
return self.name
class Teacher(db.Model):
__tablename__ = "tb_teacher"
id = db.Column(db.Integer, primary_key=True, comment="主键ID")
name = db.Column(db.String(250), comment="姓名")
sex = db.Column(db.Boolean, default=False, comment="性别")
option = db.Column(db.Enum("老师", "助教", "班主任"), default="老师", comment="职位")
def __repr__(self): # 定义 __repr__ 是为了方便调试,你可以不定义,也可以定义的更详细一些。
return self.name
class Course(db.Model):
__tablen__ = "tb_course"
id = db.Column(db.Integer, primary_key=True, comment="主键ID")
name = db.Column(db.String(250),comment="课程名称")
price = db.Column(db.Numeric(6.2)) # 设置小数精度,一共6位小数点后面2位
def __repr__(self):
return self.name
@app.route('/')
def index():
"""数据库基本操作"""
"""添加数据"""
# 添加一条数据
# student1 = Student(name='小灰',age=16,money=100,sex=True)
# db.session.add(student1)
# db.session.commit()
# 批量添加多条数据
# data_list = [
# Student(name="xiaohui1号",age=16,money=1000, sex=True),
# Student(name="xiaohui2号",age=16,money=1000, sex=True),
# Student(name="xiaohui3号",age=16,money=1000, sex=True),
# Student(name="xiaohui4号",age=16,money=1000, sex=True),
# Student(name="xiaohui5号",age=16,money=1000, sex=True),
# Student(name="xiaohui6号",age=16,money=1000, sex=True),
# ]
# db.session.add_all(data_list)
# db.session.commit()
"""查询数据"""
# 根据主键ID查询一条数据,如果ID不存在,则返回None不会报错!
# student = Student.query.get(100)
# if student is None:
# print("当前学生不存在!")
# else:
# print(student)
# print(student.name,student.age)
# 根据查询条件获取一条数据
# 模型.query.filter(模型.字段==条件值).first()
# student = Student.query.filter(Student.id==1).one() # 返回最多一个结果,而且以单项形式,而不是只有一个元素的tuple形式返回这个结果
# print(student)
# print(student.name, student.age)
# 根据查询条件获取多条数据
# 模型.query.filter(模型.字段==条件值).all()
# student = Student.query.filter(Student.id<5).first()
# print(student)
"""更新数据"""
# 先查询后修改
# student = Student.query.filter(Student.name=='小灰').first()
# student.money += 1000
# db.session.commit()
# 直接根据条件修改
# Student.query.filter(Student.name == "小灰", Student.money == 1100)\
# .update({Student.money: 2000}) # 乐观锁
# 实现类似django的F函数效果,字段值累加
# Student.query.filter(Student.name == '小灰').update({Student.money: Student.money+50})
# db.session.commit()
"""删除数据"""
# 先查询后删除
# student = Student.query.filter(Student.name == 'xiaohui6号').first()
# db.session.delete(student)
# db.session.commit()
# 直接根据条件进行删除操作
student = Student.query.filter(Student.name == "xiaohui5号").delete()
db.session.commit()
return 'ok'
if __name__ == '__main__':
# with app.app_context():
# db.create_all() # 根据模型创建所有的数据表
# # db.drop_all() # 删除模型对应的所有数据表
app.run()
过滤器 | 说明 |
---|---|
filter() | 把过滤器添加到原查询上,返回一个新查询 |
filter_by() | 把等值过滤器添加到原查询上,返回一个新查询 |
limit() | 使用指定的值限定原查询返回的结果 |
offset() | 偏移原查询返回的结果,返回一个新查询 |
order_by() | 根据指定条件对原查询结果进行排序,返回一个新查询 |
group_by() | 根据指定条件对原查询结果进行分组,返回一个新查询 |
方法 | 说明 |
---|---|
all() | 以列表形式返回查询的所有结果 |
first() | 返回查询的第一个结果,如果未查到,返回None |
first_or_404() | 返回查询的第一个结果,如果未查到,返回404 |
get() | 返回指定主键对应的行,如不存在,返回None |
get_or_404() | 返回指定主键对应的行,如不存在,返回404 |
count() | 返回查询结果的数量 |
paginate() | 返回一个Paginate分页器对象,它包含指定范围内的结果 |
having | 返回结果中符合条件的数据,必须跟在group by后面,其他地方无法使用。 |
get():参数为数字,表示根据主键查询数据,如果主键不存在返回None
Student.query.get()
all()返回查询到的所有对象
Student.query.all()
first()返回查询到的第一个对象【first获取一条数据,all获取多条数据】
Student.query.first()
filter模糊查询,支持各种运算符和查询方法
from flask import Flask, render_template, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import or_, and_, not_
import os
app = Flask(__name__, template_folder='templates')
class Config(object):
DEBUG = True
SECRET_KEY = os.urandom(24) # 随机生成一个密钥
# 数据库链接配置 = 数据库名称://登录账号:登录密码@数据库主机IP:数据库访问端口/数据库名称?charset=编码类型
SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]:3306/students?charset=utf8mb4"
# 动态追踪修改设置,如未设置只会提示警告
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 查询时会显示原始SQL语句
SQLALCHEMY_ECHO = True
app.config.from_object(Config)
# 初始化SQLAlchemy
db = SQLAlchemy() # 初始化数据库操作对象
db.init_app(app) # 初始化数据库链接
# 创建模型类
class Student(db.Model):
# 表结构声明
__tablename__ = "tb_student"
# 字段声明
id = db.Column(db.Integer, primary_key=True, comment="主键ID") # 字段类型
name = db.Column(db.String(250), comment="姓名")
age = db.Column(db.Integer, comment="年龄")
sex = db.Column(db.Boolean, default=False, comment="性别")
# DECIMAL设置小数精度,一共八位小数点后面两位 ,允许有空值,comment为列注释
money = db.Column(db.DECIMAL(8,2), nullable=True, comment="钱包")
def __repr__(self): # 定义 __repr__ 是为了方便调试,你可以不定义,也可以定义的更详细一些。
return self.name
class Teacher(db.Model):
__tablename__ = "tb_teacher"
id = db.Column(db.Integer, primary_key=True, comment="主键ID")
name = db.Column(db.String(250), comment="姓名")
sex = db.Column(db.Boolean, default=False, comment="性别")
option = db.Column(db.Enum("老师", "助教", "班主任"), default="老师", comment="职位")
def __repr__(self): # 定义 __repr__ 是为了方便调试,你可以不定义,也可以定义的更详细一些。
return self.name
class Course(db.Model):
__tablen__ = "tb_course"
id = db.Column(db.Integer, primary_key=True, comment="主键ID")
name = db.Column(db.String(250),comment="课程名称")
price = db.Column(db.Numeric(6.2)) # 设置小数精度,一共6位小数点后面2位
def __repr__(self):
return self.name
@app.route('/0')
def index0():
"""数据库基本操作"""
"""添加数据"""
# 添加一条数据
# student1 = Student(name='小灰',age=16,money=100,sex=True)
# db.session.add(student1)
# db.session.commit()
# 批量添加多条数据
# data_list = [
# Student(name="xiaohui1号",age=16,money=1000, sex=True),
# Student(name="xiaohui2号",age=16,money=1000, sex=True),
# Student(name="xiaohui3号",age=16,money=1000, sex=True),
# Student(name="xiaohui4号",age=16,money=1000, sex=True),
# Student(name="xiaohui5号",age=16,money=1000, sex=True),
# Student(name="xiaohui6号",age=16,money=1000, sex=True),
# ]
# db.session.add_all(data_list)
# db.session.commit()
"""查询数据"""
# 根据主键ID查询一条数据,如果ID不存在,则返回None不会报错!
# student = Student.query.get(100)
# if student is None:
# print("当前学生不存在!")
# else:
# print(student)
# print(student.name,student.age)
# 根据查询条件获取一条数据
# 模型.query.filter(模型.字段==条件值).first()
# student = Student.query.filter(Student.id==1).one() # 返回最多一个结果,而且以单项形式,而不是只有一个元素的tuple形式返回这个结果
# print(student)
# print(student.name, student.age)
# 根据查询条件获取多条数据
# 模型.query.filter(模型.字段==条件值).all()
# student = Student.query.filter(Student.id<5).first()
# print(student)
"""更新数据"""
# 先查询后修改
# student = Student.query.filter(Student.name=='小灰').first()
# student.money += 1000
# db.session.commit()
# 直接根据条件修改
# Student.query.filter(Student.name == "小灰", Student.money == 1100)\
# .update({Student.money: 2000}) # 乐观锁
# 实现类似django的F函数效果,字段值累加
# Student.query.filter(Student.name == '小灰').update({Student.money: Student.money+50})
# db.session.commit()
"""删除数据"""
# 先查询后删除
# student = Student.query.filter(Student.name == 'xiaohui6号').first()
# db.session.delete(student)
# db.session.commit()
# 直接根据条件进行删除操作
student = Student.query.filter(Student.name == "xiaohui5号").delete()
db.session.commit()
return 'ok'
@app.route('/')
def index():
"""数据库进阶操作"""
"""filter设置判断条件
== 判断相等
>=
<
>
<=
!=
"""
# studnet = Student.query.filter(Student.age<=15).all()
# if not studnet:
# return jsonify({'error': '404', 'errmsg': '没有如何条件的年龄!'})
# print(studnet,type(studnet))
"""filter设置模糊查询"""
# like模糊条件
# 模型.字段.like("%值%") 等价于 模型.字段.contains("值") 包含xxx
# 模型.字段.like("值%") 等价于 模型.字段.startswith("值") 以xxx开头
# 模型.字段.like("%值") 等价于 模型.字段.endswith("值") 以xxx结尾
# 模型.字段.like("__") 值长度为2个字符的.几个下划线代表几个字符
# student_list = Student.query.filter(Student.name.like('%xiao%')).all()
# student_list = Student.query.filter(Student.name.like('%3号')).all()
# student_list = Student.query.filter(Student.name.like('__')).all()
# print(student_list)
"""filter_by设置精确条件查找数据"""
# filter_by 只支持一个等号作为判断条件,而且字段左边不需要声明模型类名
# 可以用于获取一条数据,也可以获取多条数据
# student = Student.query.filter_by(age=16).first()
"""filter多条件查询"""
# 多条件需要基于逻辑运算来编写,当然,可以其他的声明方式
"""and_ 并且, 与"""
# student = Student.query.filter(and_(Student.age<20,Student.name.like('%xiao%'))).all()
"""or_ 或者,或"""
# student = Student.query.filter(or_(Student.age==16,Student.age>20)).all()
"""not_ 排除,非"""
# student = Student.query.filter(not_(Student.age==16)).all()
"""filter值范围查询"""
# 查询年龄=15或者17或者19的
# student = Student.query.filter(Student.age.in_([15,17,19])).all()
"""order_by结果排序"""
# order_by(模型.字段.desc()) db.desc(模型.字段) 倒序
# order_by(模型.字段.asc()) db.asc(模型.字段) 升序
# student = Student.query.order_by(db.desc(Student.age)).all()
# student = Student.query.order_by(db.asc(Student.age)).all()
"""count 统计结果数量"""
# student = Student.query.filter(Student.sex==1).count()
"""limit 结果数量进行限制"""
"""offset 对查询开始位置进行设置"""
student = Student.query.order_by(Student.money.desc()).offset(2).limit(3).all()
# print(student)
"""paginate分页器"""
# paginate(page=当前页码, per_page=每一页数据量, max_per_page=每一页最大数据量)
# 当前页码,默认是从request.args["page"],如果当前参数没有值,则默认为1
# 每一页数据量,默认是100条
# 因为分页器有提供了一个 request.args.["per_page"]给客户端设置每一页数据量,所以再次限定客户端最多能设置的每一页数据量
# pagination = Student.query.filter(Student.sex==True).paginate(per_page=1)
# print(pagination)
# print( pagination.items ) # 获取当前页数据量
# print( pagination.has_next ) # 如果还有下一页数据,则结果为True
# print( pagination.has_prev ) # 如果有上一页数据,则结果为True
# print( pagination.page ) # 当前页页码 request.args.get("page",1)
# print( pagination.total ) # 本次查询结果的数据总量[被分页的数据量总数]
# print( pagination.pages ) # 总页码
# print( pagination.prev() ) # 上一页的分页器对象,如果没有上一页,则默认为None
# print( pagination.next() ) # 下一页的分页器对象,如果没有下一页,则默认为None
# if pagination.has_next:
# print( pagination.next().items ) # 下一页的数据列表
# return render_template('list.html',pagination=pagination)
return jsonify({'ok': '202'})
if __name__ == '__main__':
# with app.app_context():
# db.create_all() # 根据模型创建所有的数据表
# # db.drop_all() # 删除模型对应的所有数据表
app.run()
list.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
.page a,.page span{
padding: 2px 6px;
color: #fff;
background: #6666ff;
text-decoration: none;
}
.page span{
color: #fff;
background: orange;
}
style>
head>
<body>
<table border="1" align="center" width="600">
<tr>
<th>IDth>
<th>ageth>
<th>nameth>
<th>sexth>
<th>moneyth>
tr>
{% for student in pagination.items %}
<tr>
<td>{{ student.id }}td>
<td>{{ student.age }}td>
<td>{{ student.name }}td>
<td>{{ "男" if student.sex else "女" }}td>
<td>{{ student.money }}td>
tr>
{% endfor %}
<tr align="center">
<td colspan="5" class="page">
{% if pagination.has_prev %}
首 页a>
<a href="?page={{ pagination.prev_num }}">上一页a>
<a href="?page={{ pagination.prev_num }}">{{ pagination.prev_num }}a>
{% endif %}
<span>{{ pagination.page }}span>
{% if pagination.has_next %}
<a href="?page={{ pagination.next_num }}">{{ pagination.next_num }}a>
<a href="?page={{ pagination.next_num }}">下一页a>
<a href="?page={{ pagination.pages }}">尾 页a>
{% endif %}
td>
tr>
table>
body>
html>
分组查询和分组查询结果过滤
一般分组都会结合聚合函数来一起使用。SQLAlchemy中所有的聚合函数都在func
模块中声明的。
from sqlalchemy import func
函数名 | 说明 |
---|---|
func.count | 统计总数 |
func.avg | 平均值 |
func.min | 最小值 |
func.max | 最大值 |
func.sum | 和 |
代码视图:
@app.route("/")
def index():
from sqlalchemy import func
""" group_by 分组查询"""
# 查询男生和女生的最大年龄
# ret = db.session.query(Student.sex,func.max(Student.age)).group_by(Student.sex).all()
# print(ret)
# 查询出男生和女生年龄大于18的人数
# having是针对分组的结果进行过滤处理,所以having能调用的字段,必须是分组查询结果中的字段,否则报错!!
# ret = db.session.query(Student.sex,Student.age, func.count(Student.age)).group_by(Student.sex,Student.age).having(Student.age>18).all()
# print(ret)
"""执行原生SQL语句,返回结果不是模型对象, 是列表和元祖"""
# 查询多条
# ret = db.session.execute("select id,name,age,IF(sex,'男','女') from tb_student").fetchall()
# print(ret)
# # 查询单条
# ret = db.session.execute("select * from tb_student where id = 3").fetchone()
# print(ret)
# 添加/修改/删除
# db.session.execute("UPDATE tb_student SET money=(money + %s) WHERE age = %s" % (200, 22))
# db.session.commit()
# 查询出女生和男生中大于18岁的人数
ret = db.session.execute("SELECT IF(sex,'男','女'), count(id) from (SELECT id,name,age,sex FROM `tb_student` WHERE age>18) as stu group by sex").fetchall()
print(ret)
return "Ok"
执行原生SQL语句:
"""执行原生SQL语句,返回结果不是模型对象, 是列表和元祖"""
# 查询多条
# ret = db.session.execute("select id,name,age,IF(sex,'男','女') from tb_student").fetchall()
# print(ret)
# # 查询单条
# ret = db.session.execute("select * from tb_student where id = 3").fetchone()
# print(ret)
# 添加/修改/删除
# db.session.execute("UPDATE tb_student SET money=(money + %s) WHERE age = %s" % (200, 22))
# db.session.commit()
# 查询出女生和男生中大于18岁的人数
ret = db.session.execute("SELECT IF(sex,'男','女'), count(id) from (SELECT id,name,age,sex FROM `tb_student` WHERE age>18) as stu group by sex").fetchall()
print(ret)