摘要:的模型使用模型的原因当项目越来越大的时候会出现很多问题原生较多重复使用率低如果你的数据库发生了改变所有的原生就都要进行修改写原生的时候会有安全隐患中文件关系对象的映射使用去操作数据库的时候不会再去写原生的了通过把表映射成类字段为你的属性在
Flask-SQLalchemy flask的ORM模型 使用ORM模型的原因
当项目越来越大的时候 会出现很多问题
原生SQL较多 重复使用率低
如果你的数据库发生了改变 所有的原生SQL就都要进行修改
写原生SQL的时候 会有安全隐患
ORM:中文件关系对象的映射 使用ORM去操作数据库的时候 不会再去写原生的SQL了 通过把表映射成 类 字段为你的属性 ORM在执行的时候 也会最终转换为 SQL语句 去操作数据库
易用性 使用ORM可以减少重复SQL的概率 写出来的模型也更加的直观清晰
可移植性 ORM支持很多不同的数据库
安装:
sudo pip3 install flask-sqlalchemy
一、执行原生SQL (1) 创建数据库create database if not exists 库名 character set utf8;
(2) 安装pymysqlsudo pip3 install pymysql
(3) 配置数据库DB_URI = "mysql+pymysql://用户名:密码@主机:端口号/库名"
实例
from sqlalchemy import create_engine DATABASE = "hz03" USERNAME = "root" PASSWORD = "123456" HOST = "127.0.0.1" PORT = "3306" #创建连接和操作数据库的URI DB_URI = "mysql+pymysql://{}:{}@{}:{}/{}".format(USERNAME,PASSWORD,HOST,PORT,DATABASE) #创建操作数据库的引擎 engine = create_engine(DB_URI) with engine.connect() as con: # con.execute("create table user(id int,username varchar(255),sex tinyint)") con.execute("insert into user values(1,"xxx",1)")二、在flask中使用ORM (1) 当前字段类型
类型名 | 说明 |
---|---|
integer | 整形 |
SmallInteger | 小整形 |
BigInteger | 长整型 |
Float | 浮点型 |
String | varchar类型 |
Text | 长文本 |
Boolean | tingint |
Date | 日期 datetime.date |
Time | 时间 datetime.time |
DateTime | 时间和日期 datetime.datetim |
选项 | 选项说明 |
---|---|
primary_key | 主键 默认 False |
index | 常规 默认 False |
Unique | 唯一 默认 False |
nullable | 是否为null 默认True |
default | 默认值 |
注意:
其中的default默认值 并不是更改表结构的默认值 而是在插入数据的时候 如果不插入数据 则插入默认值
实例
配置from flask import Flask,render_template from flask_script import Manager from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) #创建连接数据的URI app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/hz03" app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True #开启自动提交 #数据的追踪 当数据发生改变时 会返回信号量 进行关闭 app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db = SQLAlchemy(app) manager = Manager(app)创建模型
class User(db.Model): id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(20),index=True) age = db.Column(db.Integer) icon = db.Column(db.String(40),default="default.jpg")数据的添加修改删除
@app.route("/create_table/") def create_table(): db.drop_all() #删除 和当前模型类同名的表 db.create_all() #创建当前模型类的表 return "创建表" @app.route("/insert/") def insert(): try: u = User(username="张三",age=18) # print(u) db.session.add(u) db.session.commit() #因为sqlalchemy开启事物 所有所以需要提交或者回滚 except: db.session.rollback() return "添加数据" #开启了自动提交功能 不需要手动commit了 @app.route("/insert_two/") def insert_two(): u = User(username="李四",age=20) db.session.add(u) return "走我了" #修改 @app.route("/update/") def update(): u = User.query.get(1) # print(u.id) # print(u.username) u.username = "王五" db.session.add(u) return "update" #删除 @app.route("/delete/") def delete(): u = User.query.get(2) #查询成功返回 对象 失败返回None # print(u) db.session.delete(u) return "删除"拆分MVT 目录结构
project/ App/ __init__.py 包文件必须的 model.py 模块 views.py 视图 ext.py extensions.py 加载第三方扩展的文件 settings.py 配置文件 static/ templates/ manage.py 启动项细致的
project/ App/ __init__.py static/ js/ img/ upload/ css/ templates/ common/ ... forms/ __init__.py ... models/ __init__.py views/ __init.py__.py ... settings.py email.py extensions.py manager.py migrations/ venv/三、数据的操作
创建模型类
class User(Base,db.Model): __tablename__ = "user" #给表起名 id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(20),index=True) age = db.Column(db.Integer) icon = db.Column(db.String(40),default="default.jpg") def __init__(self,username="",age=0,icon="default.jpg"): self.username = username self.age = age self.icon = icon(1) 添加 add add_all 添加一条
@main.route("/add/") def add(): u = User(username="张三",age=18) db.session.add(u) db.session.commit() return "数据添加一条成功"添加多条
@main.route("/add_all/") def add_all(): u1 = User(username="李四",age=20) u2 = User(username="王五",age=22) db.session.add_all([u1,u2]) db.session.commit() return "添加多条"(2) 自定义增删改的基础类
class Base: #定义一个添加一条数据的方法 def save(self): try: db.session.add(self) db.session.commit() except: db.session.rollback() #定义添加多条数据的方法 @staticmethod def save_all(*args): try: db.session.add_all(args) db.session.commit() except: db.session.rollback() #自定义删除方法 def delete(self): try: db.session.delete(self) db.session.commit() except: db.session.rollback()
使用
class User(Base,db.Model): ...
在视图中使用
@main.route("/add/") def add(): # u = User(username="张三",age=18) u = User("张三",18) # db.session.add(u) # db.session.commit() u.save() #使用自定义的添加方法 return "数据添加一条成功" @main.route("/add_all/") def add_all(): # u1 = User(username="李四",age=20) # u2 = User(username="王五",age=22) u1 = User("赵六",27) u2 = User("李七",12) # db.session.add_all([u1,u2]) # db.session.commit() User.save_all(u1,u2) return "添加多条" @main.route("/delete/") def delete(): u = User.query.get(1) u.delete() return "删除"四、数据库操作 查询集
查询数据的集合
分类
原始查询集
类名.query得到的结果就为原始查询集
数据查询集
加上各种的过滤器的方法 最终返回的结果 为数据查询集 都使用数据查询集
过滤器 (1) all 查询所有 以列表形式返回 不支持连贯操作类名.query.all()
@main.route("/all/") def all(): data = User.query.all() print(data) return render_template("show.html",data=data)(2) filter() 过滤
类名.query.filter([类名.属性名 条件操作符 值])
默认返回所有
#支持连贯操作 @main.route("/filter/") def filter(): # data = User.query.filter() #返回所有 # data = User.query.filter(User.age>20) #查询年龄大于20的数据 data = User.query.filter(User.age>20,User.age<40) #查询年龄大于20的数据 and 小于40 print(data) return render_template("show.html",data=data)(3) filter_by 只支持参数为关键字参数
类名.query.filter_by(属性名=值...)
@main.route("/filter_by/") def filter_by(): # data = User.query.filter_by(id=2) # data = User.query.filter_by(id>2) #错误写法 data = User.query.filter_by(id=2,age=27) return render_template("show.html",data=data)(4) offset 偏移量
offset(num)
#偏移量取值 @main.route("/offset/") def offset(): data = User.query.filter().offset(2) return render_template("show.html",data=data)(5) limit 取值
limit(num)
@main.route("/limit/") def limit(): # data = User.query.limit(2) data = User.query.filter(User.age>30).limit(2) return render_template("show.html",data=data)(6) offset和limit组合使用
@main.route("/offsetlimit/") def offsetlimit(): data = User.query.offset(2).limit(2) # limit 2,2 return render_template("show.html",data=data)(7) order_by() 排序
@main.route("/order_by/") def order_by(): # data = User.query.order_by(User.age) #升序 data = User.query.order_by(-User.age) #降序 return render_template("show.html",data=data)(8) first 取出第一条数据 返回对象
@main.route("/first/") def first(): # data = User.query.first() == User.query.get(2) print(data) print(data.id) print(data.username) return "取出第一条数据"(9) get 获取id对应的数据
查询成功返回对象 查询失败 返回None
@main.route("/first/") def first(): data = User.query.get(2) return "取出第一条数据"(10) contains 包含关系
@main.route("/contains/") def contains(): #username中包含数字7的数据 data = User.query.filter(User.username.contains("7")) return render_template("show.html",data=data)(11) like 模糊查询
@main.route("/like/") def like(): #username中包含数字7的数据 # data = User.query.filter(User.username.like("%7%")) # data = User.query.filter(User.username.like("李%")) #以李作为开头的 data = User.query.filter(User.username.like("%6")) #以6作为结尾的数据 return render_template("show.html",data=data)(12) startswith endswith 以...开头 以...结尾
#startswith endswith @main.route("/startend/") def startend(): # data = User.query.filter(User.username.startswith("李")) data = User.query.filter(User.username.endswith("6")) return render_template("show.html",data=data)(13) 比较运算符
__gt__
__ge__
__lt__
__le__
>
<
>=
<=
==
!=
@main.route("/bjiao/") def bjiao(): # data = User.query.filter(User.age.__gt__(20)) # data = User.query.filter(User.age.__ge__(99)) data = User.query.filter(User.age!=99) return render_template("show.html",data=data)(14) in 和 not in
@main.route("/in/") def myIn(): # data = User.query.filter(User.age.in_([27,12,1,30,40,50])) data = User.query.filter(~User.age.in_([27,12,1,30,40,50])) return render_template("show.html",data=data)(15) is null
@main.route("/null/") def null(): # data = User.query.filter(User.username == None) # data = User.query.filter(User.username != None) # data = User.query.filter(User.username.is_(None)) data = User.query.filter(User.username.isnot(None)) return render_template("show.html",data=data)(16) and_
多个条件 用逗号隔开,为and操作
from sqlalchemy import and_
@main.route("/and/") def myAnd(): # data = User.query.filter(User.age==27,User.id==2) data = User.query.filter(and_(User.age==27,User.id==2)) return render_template("show.html",data=data)(17) or_
from sqlalchemy import or_
@main.route("/and/") def myAnd(): data = User.query.filter(or_(User.age==27,User.id==2)) data = User.query.filter(and_(User.username.like("%6%")),or_(User.age>=27,User.id==2)) return render_template("show.html",data=data)(18) not_
from sqlalchemy import not_
@main.route("/and/") def myAnd(): # data = User.query.filter(not_(User.age>27,User.id==1)) #错误写法只能给一个条件取反 data = User.query.filter(not_(User.age>27)) return render_template("show.html",data=data)(19) count 统计
data = User.query.filter(not_(User.age>27)).count()四、文件的迁移
模块:
pip install flask-migrate
pip install flask-script
使用 (1) 实例化from flask_migrate import Migrate,MigrateCommand from flask_sqlalchemy import SQLalchemy app = Flask(__name__) db = SQLalchemy(app) migrate = Migrate(app,db=db) manager = Manager(app) manager.add_command("db",MigrateCommand)(2) 初始化 迁移文件目录
python manage.py db init
(3) 生成迁移文件python manage.py db migrate
(4) 执行迁移文件python manage.py db upgrade
注意
如果当前存在 模型 但是执行创建迁移文件的时候 提示没有任何改变的时候 需要查看当前的模型类是否有使用(导入)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/41833.html
摘要:文件上传邮件发送一原生文件上传修改头像提交文件上传的视图函数有文件上传了拿到文件名称图片上传保存的路径使用和渲染文件上传自定义一个文件上传的表单类修改头像文件不能为空该文件类型不允许上传提交生成随机的图片名称获取图片大小设置尺寸当前缩放 文件上传邮件发送 一、原生文件上传 form.html 修改头像 manage.py...
摘要:我们的论坛项目就使用了该框架。此外,麦子学院也有一个入门视频教程,一共小时的视频教程,涵盖开发的方方面面,包括环境的搭建,语法介绍,项目结构的组织,全球化,单元测试等内容。博客地址更多阅读的机制三个框架的对比 前面两篇文章中我们已经了解 Web(HTTP)服务器,Web应用程序,Web框架,WSGI这些 Python Web 开发中的概念。我们知道,Web框架通过将不同Web应用程序中...
摘要:表单一原生表单原生表单用户名请输入用户名密码请输入密码提交接收表单的数据提交过来了将俩个路由地址合并为同一个二使用表单扩展库作用是一个用于表单处理的扩展库提供表单的校验的功能使用字段类型字段名称字段类型普通文本字段密码框提交按钮多行文本 flask 表单 一、原生表单 form.html {% extends common/base.html %} {% block title %} ...
阅读 2685·2021-11-19 11:35
阅读 2520·2021-11-02 14:40
阅读 1332·2021-09-04 16:48
阅读 2952·2019-08-30 15:55
阅读 1648·2019-08-30 13:11
阅读 1894·2019-08-29 11:12
阅读 1033·2019-08-27 10:52
阅读 3093·2019-08-26 18:36