​ Web程序开发中最重要的莫过于关系型数据库,即SQL 数据库,另外文档数据库(如 mongodb)、键值对数据库(如 redis)慢慢变得流行.

原因 : 我们不直接使用这些数据库引擎提供的 Python 包,而是使用对象关系映射(Object-Relational Mapper, ORM)框架,是因为它将低层的数据库操作指令抽象成高层的面向对象操作。也就是说,如果我们直接使用数据库引擎,我们就要写 SQL 操作语句,但是,如果我们使用了 ORM 框架,我们对诸如表、文档此类的数据库实体就可以简化成对 Python 对象的操作。

(1) Flask - SQLAlchemy

Flask使用的ORM框架为 SQLAlchemy,数据库采用了URL指定,下面我们列举几种数据库引擎:

数据库引擎 URL指定
MySQL mysql://username:password@hostname/database
Postgres postgresql://username:password@hostname/database
SQLite (Unix) sqlite:////absolute/path/to/database
SQLite (Windows) sqlite:///c:/absolute/path/to/database

注意:

  1. username 和 password 表示登录数据库的用户名和密码
  2. hostname 表示 SQL 服务所在的主机,可以是本地主机(localhost)也可以是远程服务器
  3. database 表示要使用的数据库 , SQLite 数据库不需要使用服务器,它使用硬盘上的文件名作为 database

ORM使用的优点:

  1. 增加少sql的重复使用率
  2. 使表更加的可读性
  3. 可移植性

(2) SQLAlchemy操作sql原生

安装操作数据库的模块

pip3 install pymysql

安装 flask-sqlalchemy

sudo pip3 install flask-sqlalchemy

配置路径

DB_URI = 'mysql+pymysql://root:password@host:port/database'

下面先看下sqlalchemy操作的写法:

from sqlalchemy import create_engine

HOST = '127.0.0.1'
USERNAME = 'root'
PASSWORD = '123456'
DATABASE = 'demo' #数据库名
PORT = 3306
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOST,PORT,DATABASE)
#创建引擎
engine = create_engine(DB_URI) with engine.connect() as db:
data = db.execute('select * from user') #从user表中获取全部数据
db.execute('delete from user where id=1') #删除id=1的数据

(3) 设计数据表

1 字段类型

类型名 python中的类型 说明
Integer int 存储整形 32位
SmallInteger int 小整形 16为
BigInteger int 大整形
Float float 浮点数
String str 字符串 varchar
Text str 长文本
Boolean bool bool值
Date datetimedate 日期
Time datetime.time 时间
datetime datetime.datetime 时间日期

2 可选条件

选项 说明
primary_key 主键, 如果设为True,表示主键
unique 唯一索引 ,如果设为True,这列唯一
index 常规索引, 如果设为True,创建索引,提升查询效率
nullable 是否可以为null 默认True
default 默认值

(4)在flask中使用ORM模型

下面我们使用ORM模型

from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:20111673@127.0.0.1:3306/demo'
db = SQLAlchemy(app) # manager = Manager(app) #创建User用户,表名为user
class User(db.Model):
__table__name = 'user'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(20),index=True)
sex = db.Column(db.Boolean,default=True)
info = db.Column(db.String(50)) # 定义一个视图函数
@app.route('/create')
def create():
# db.drop_all() #删除仅为模型表
db.create_all() #创建模型表
return '创建成功' if __name__ == '__main__':
manager.run()

(5)增加数据

添加数据方式1

#方式1
# sqlalchemy默认开启了事务处理
@app.route('/insert/')
def insert():
try:
u = User(username='WANGWU',info='personal WANGWU message')
db.session.add(u) #添加数据对象
db.session.commit() #事务提交
except:
db.session.rollback()#事务回滚
return '添加单条数据!' @app.route('/insertMany/')
def insertMany():
u1 = User(username='name1',info='personal name1 message')
u2 = User(username='name2',info='personal name2 message')
db.session.add_all([u1,u2]) #以add_all(数据对象列表)
db.session.commit() #
return '添加多条数据!'

添加数据方式2

#方式2
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True #在app设置里开启自动提交
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False #关闭数据追踪,避免内存资源浪费 @app.route('/insertMany/')
def insertMany():
u1 = User(username='name1',info='personal name1 message')
u2 = User(username='name2',info='personal name2 message')
db.session.add_all([u1,u2])
return '提交多条数据'

(6)更新与删除

# 类名.query  返回对应的查询集
# 类名.query.get(查询条件) 返回对应的查询对象
@app.route('/update/')
def update():
u = User.query.get(1)
u.username = 'update name' #更新内容
db.session.add(u) #进行添加
return 'update' # 删除数据
@app.route('/delete/')
def delete():
u = User.query.get(2) #找到对应的查询集对象
db.session.delete(u) # 删除对应的u对象
return 'delete id=2'

(7) 拆分MVT

目录结构

project/
manage.py #启动项存放
ext.py #作为当前sqlalchemy扩展
settings.py #配置存放
app/
__init__.py
models.py #应用models.py
views.py #应用视图views.py
templates/ #模板目录
static/ #静态文件目录

ext.py SQLAlchemy扩展

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy() #实例化db对象

蓝本view view.py视图函数

from flask import Blueprint
from .models import User
from ext import db
#创建蓝本view
view = Blueprint('view',__name__)
#定义视图函数
@view.route('/')
def index():
return 'index' @view.route('/insert/')
def insert():
u = User(username='张三',info='个人信息')
db.session.add(u)
return 'insert success'

蓝本view models.py模型类

from ext import db  #导入db
#构建User模型类
class User(db.Model,Base):
__table__name = 'user'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(20),index=True)
sex = db.Column(db.Boolean,default=True)
info = db.Column(db.String(50))

manage.py启动项

from flask import Flask
from flask_script import Manager
from ext import db
import settings
from app.view import view app = Flask(__name__)
#将系统配置项Config类加载到app
app.config.from_object(settings.Config)
#通过db对象将app初始化
db.init_app(app)
#将蓝图view注册进app
app.register_blueprint(view)
manager = Manager(app) if __name__ == '__main__':
manager.run()

setting.py配置文件

class Config:
#设置mysql+pymysql的连接
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:20111673@127.0.0.1:3306/demo'
#加密设置
SECRETE_KEY = 'secret_key'
#关闭数据追踪
SQLALCHEMY_TRACK_MODIFICATIONS = False
#开启提交
SQLALCHEMY_COMMIT_ON_TEARDOWN = True

前面我们采用系统的每次自动提交session 即SQLALCHEMY_COMMIT_ON_TEARDOWN

但是如果想自己定义提交方式,同时不想传入关键字参数,那么该怎样入手呢?这里提供一种思路

(8) 自定义增删改类

我们对模型类进行了修改,models.py 内容如下:

from ext import db
#定义了base基类
class Base:
def save(self):
try:
db.session.add(self) #self实例化对象代表就是u对象
db.session.commit()
except:
db.session.rollback()
#定义静态类方法接收List参数
@staticmethod
def save_all(List):
try:
db.session.add_all(List)
db.session.commit()
except:
db.session.rollback()
#定义删除方法
def delete(self):
try:
db.session.delete(self)
db.session.commit()
except:
db.session.rollback()
#定义模型user类
class User(db.Model,Base):
__table__name = 'user'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(20),index=True)
sex = db.Column(db.Boolean,default=True)
info = db.Column(db.String(50))
#
def __init__(self,username='',info='',sex=True):
self.username = username
self.info = info
self.sex = sex
#注意:
#原实例化: u = User(username='张三',info='个人信息')
#现实例化: u = User('李四','李四个人信息')

在views.py中使用

from flask import Blueprint
from .models import User
from ext import db view = Blueprint('view',__name__) @view.route('/')
def index():
return 'index'
#插入单条数据
@view.route('/insert/')
def insert():
# u = User(username='test',info='default')
u = User('xiaomeng','default')
u.save()
db.session.add(u)
return 'insert success'
#保存多条数据
@view.route('/saveMany/')
def saveMany():
u1 = User('zhan123','default123')
u2 = User('li123','default message')
User.save_all([u1,u2])
return 'add many'
#删除数据
@view.route('/delete/')
def delete():
u = User.query.get(1) #获取查询集
u.delete()
return 'delete message'

其他都不做改变,基本思路是封装到类,通过多继承来实现方法的调用。

Flask入门数据库框架flask-SQLAlchemy(十)的更多相关文章

  1. Flask 入门一( flask 框架和 flask-script 库)

    Flask 入门一( flask 框架 和 flask-script 库) 一.Flask框架: 1.简介 Flask是一个非常小的Python Web框架,被称为微型框架:只提供了一个稳健的核心,其 ...

  2. Flask入门数据库的查询集与过滤器(十一)

    1 查询集 : 指数据查询的集合 原始查询集: 不经过任何过滤返回的结果为原始查询集 数据查询集: 将原始查询集经过条件的筛选最终返回的结果 查询过滤器: 过滤器 功能 cls.query.filte ...

  3. 超实用的Flask入门基础教程,新手必备!

    Flask入门基础教程 Flask简介 Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活.轻便.安全且容易上手.它可以很好地结合MVC模式进行开发,开发人员分工合 ...

  4. flask的orm框架(SQLAlchemy)-创建表

    # 转载请留言联系 ORM 是什么? ORM,Object-Relation Mapping.意思就是对象-关系映射.ORM 主要实现模型对象到关系数据库数据的映射. 优点 : 只需要面向对象编程, ...

  5. Flask入门到放弃(四)—— 数据库

    转载请在文章开头附上原文链接地址:https://www.cnblogs.com/Sunzz/p/10979970.html 数据库操作 ORM ORM 全拼Object-Relation Mappi ...

  6. 测开之路一百四十二:ORM框架之SQLAlchemy建库、建表、数据库操作

    flask-SQLAlchemy是在原生SQLAlchemy的基础之上做了一层封装,安装flask-SQLAlchemy会自动安装SQLAlchemy 安装 传统的sql建表建字段 通过flask-S ...

  7. pthon web框架flask(二)--快速入门

    快速入门 迫切希望上手?本文提供了一个很好的 Flask 介绍.假设你已经安装 Flask, 如果还没有安装话,请浏览下 安装 . 一个最小的应用 一个最小的应用看起来像这样: from flask ...

  8. Django,Flask,Tornado三大框架对比,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Django 与 Tornado 各自的优缺点Django优点: 大和全(重量级框架)自带orm,template,view 需要的功能也可以去找第三方的app注重高效开发全自动化的管理后台(只需要使 ...

  9. Python框架 Flask 项目实战教程

    本文目的是为了完成一个项目用到的flask基本知识,例子会逐渐加深.最好对着源码,一步一步走.下载源码,运行pip install -r requirements.txt 建立环境python db_ ...

随机推荐

  1. UVA_11624 Fire! 【BFS】

    一.题面 略 二.题意分析 一个迷宫中,有一个人Joe和一个或多个起火点,起火点可以蔓延,人可以走动,都只能走4个方向,问人能走出去的最少步数,如果不能输出不可能.很多大佬说是两遍BFS,先一遍火,记 ...

  2. Codeforces1114 D. Flood Fill (DP)(整个区间染成同色)

    题意:连续的几个颜色相同的格子称为一个连通块.选一个点为起点,每个操作是把所在连通块变一个颜色,求把整个区间染成同色需要的最少操作数.(注意,每次只能改变所在连通块的颜色,不能任选连通块,除了最开始时 ...

  3. window7下karma 报 The header content contains invalid characters BUG

    打开你的依赖node_modules\karma\node_modules\connect\lib\patch.js 将里面的setHeader方法改成下面这样,干掉序列化日期时出现的中文 res.s ...

  4. POJ - 1061 扩展gcd

    题意:求\((n-m)t+Lk=x-y\)的解\(t\) #include<iostream> #include<algorithm> #include<cstdio&g ...

  5. A - TOYS(POJ - 2318) 计算几何的一道基础题

    Calculate the number of toys that land in each bin of a partitioned toy box. 计算每一个玩具箱里面玩具的数量 Mom and ...

  6. v-for遍历对象

    如果数据是这样的: userInformation:{ 'aa':{ user_name:'ddd123', icon:'', pic:'', addTime:'2018-3-21 11:21', c ...

  7. js 中 forEach 和 map

    共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前项的索引index,原始数组input. 3.匿名 ...

  8. Oracle RAC集群搭建(一)-ASM共享存储卷

    01, ASM共享存储卷 安装集群的话,必须要有共享磁盘,目的是为作裁决磁盘使用.还需要有数据文件的共享磁盘 02,规划 主机 裁决磁盘 数据 rac1        1G*1          20 ...

  9. Fragment、Activity比较——Android碎片介绍

    Fragment是Android honeycomb 3.0新增的概念,Fragment名为碎片不过却和Activity十分相似,下面介绍下Android Fragment的作用和用法.Fragmen ...

  10. pat03-树2. List Leaves (25)

    03-树2. List Leaves (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue Given a t ...