这篇将提到动态页面,连接数据库,之前的模板都是静态页面,首先要先了解一下需要用到的模块及概念。
ORM 全拼Object-Relation Mapping.
中文意为 对象-关系映射.
主要实现模型对象到关系数据库数据的映射.
比如:把数据库表中每条记录映射为一个模型对象
优点 :
只需要面向对象编程, 不需要面向数据库编写代码.
对数据库的操作都转化成对类属性和方法的操作.
不用编写各种数据库的sql语句.
实现了数据模型与数据库的解耦, 屏蔽了不同数据库操作上的差异.
不在关注用的是mysql、oracle…等.
通过简单的配置就可以轻松更换数据库, 而不需要修改代码.
缺点 :
相比较直接使用SQL语句操作数据库,有性能损失.
根据对象的操作转换成SQL语句,根据查询的结果转化成对象, 在映射过程中有性能损失
SQLAlchemy是一个基于Python实现的ORM框架。该框架建立在 DB API之上,使用关系对象映射进行数据库操作
简言之便是:将类和对象转换成SQL,然后使用数据API执行SQL并获取执行结果。
安装命令
pip install flask-sqlalchemy
注意sqlalchemy 依赖于 pymysql 模块,确保pymysql 被正确安装
pip install pymysql
SQLAlchemy常用数据类型:
- Integer:整形,映射到数据库中是int类型。
- Float:浮点类型,映射到数据库中是float类型。他占据的32位。
- Double:双精度浮点类型,映射到数据库中是double类型,占据64位。
- String:可变字符类型,映射到数据库中是varchar类型.
- Boolean:布尔类型,映射到数据库中的是tinyint类型。
- DECIMAL:定点类型。是专门为了解决浮点类型精度丢失的问题的。在存储钱相关的字段的时候建议大家都使用这个数据类型。并且这个类型使用的时候需要传递两个参数,第一个参数是用来标记这个字段总能能存储多少个数字,第二个参数表示小数点后有多少位。
- Enum:枚举类型。指定某个字段只能是枚举中指定的几个值,不能为其他值。在ORM模型中,使用Enum来作为枚举
- Date:存储时间,只能存储年月日。映射到数据库中是date类型。在Python代码中,可以使用
datetime.date
来指定 - DateTime:存储时间,可以存储年月日时分秒毫秒等。映射到数据库中也是datetime类型。在Python代码中,可以使用
datetime.datetime
来指定。示例代码如下: - Time:存储时间,可以存储时分秒。映射到数据库中也是time类型。在Python代码中,可以使用
datetime.time
来至此那个。 - Text:存储长字符串。一般可以存储6W多个字符。如果超出了这个范围,可以使用LONGTEXT类型。映射到数据库中就是text类型。
- LONGTEXT:长文本类型,映射到数据库中是longtext类型。
SQLAlchemy列选项
选项名 说明
primary_key 如果设为True,这列就是表的主键
unique 如果设为True,这列不允许出现重复的值
index 如果设为True,这列创建索引,提升查询效率
nullable 如果设为True,这列允许使用空值;如果设为False,这列不允许使用空值
default 为这列定义默认值
# 导入第三方链接库 sqlalchemy
from flask_sqlalchemy import SQLAlchemy
# 载入配置文件
app.config.from_pyfile('config.ini')
# #指定数据库连接还有库名,如果配置文件中有了这些连接操作。就可以注释
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://用户:密码@地址:端口号/库名?charset=utf8'
# 指定配置,用来省略提交操作,如果配置文件中有了提交操作。就可以注释
# app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
# 建立数据库类,用来映射数据库表,将数据库的模型作为参数传入
# db为database的缩写
class User(db.Model):
# 声明表名
__tablename__ = 'user'
# 建立字段函数
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(200))
password = db.Column(db.String(200))
@app.route('/')
def index():
# 增:入库逻辑
# 声明对象
user = User(name='你好',password='111111')
# 调用添加方法
db.session.add(user)
# 提交入库,如果配置文件中有了提交为True,这里的commit就可以注释掉
# db.session.commit()
return "这是首页"
# 数据库的删除操作,注意不要用到系统的变量,以防重名
@app.route('/deldata')
def del_data():
# 删除根据某个字段做删除
# filter_by可以理解为where 条件限定,删除id为24的数据操作
User.query.filter_by(id=24).delete()
return '这里是删除操作'
# 数据库的修改操作
@app.route('/edit')
def edit_user():
# 根据某个字段做修改操作
# update user set name = '张三' where id = 2
# 这里的update()中的参数为dict
User.query.filter_by(id=2).update({'name':'张三'})
return '这是修改方法'
# 数据库的查询操作(查)
@app.route("/select")
def select_user():
# 简单的全量查询
# 翻译为 select * from user
ulist = User.query.all() # 以为这里返回的是一个list,所以遍历取值
print(ulist)
for item in ulist:
# list的元素为object,所以用到 .name
print(item.name)
# 只取一条
# 翻译为 select * from user limit 1
# 和上边对应作比较。回想pymysql中一条数据和多条数据的读取,fetchall()和fetchone()的用法
ulist = User.query.first()
# 注意返回有可能是list,也可能是object
print(ulist)
# 使用原生的sql语句
# 是为了对数据库在查询的时候能避免不需要的问题,在我的文章中对mysql数据库的知识点梳理中有提到
# 翻译为 select * from user order by id desc limit 1,2
items = db.session.execute(' select * from user order by id desc ')
# 将结果集强转为list,原生的读取出来并不是一个list
items = list(items)
# 使用原生语句进行修改操作
# db.session.execute(" update user set password = '321321' where id = 6 ")
# 也可以将动态数据传递给模板
# 模板的使用在 Flask中的一些问题的初步汇总 中有提到
return render_template('hello.html',items=items)
if __name__ == "__main__":
app.run()
其中需要注意的点注释中有提到,不喜轻喷